Related
Is there a way in Python to pass optional parameters to a function while calling it and in the function definition have some code based on "only if the optional parameter is passed"
The Python 2 documentation, 7.6. Function definitions gives you a couple of ways to detect whether a caller supplied an optional parameter.
First, you can use special formal parameter syntax *. If the function definition has a formal parameter preceded by a single *, then Python populates that parameter with any positional parameters that aren't matched by preceding formal parameters (as a tuple). If the function definition has a formal parameter preceded by **, then Python populates that parameter with any keyword parameters that aren't matched by preceding formal parameters (as a dict). The function's implementation can check the contents of these parameters for any "optional parameters" of the sort you want.
For instance, here's a function opt_fun which takes two positional parameters x1 and x2, and looks for another keyword parameter named "optional".
>>> def opt_fun(x1, x2, *positional_parameters, **keyword_parameters):
... if ('optional' in keyword_parameters):
... print 'optional parameter found, it is ', keyword_parameters['optional']
... else:
... print 'no optional parameter, sorry'
...
>>> opt_fun(1, 2)
no optional parameter, sorry
>>> opt_fun(1,2, optional="yes")
optional parameter found, it is yes
>>> opt_fun(1,2, another="yes")
no optional parameter, sorry
Second, you can supply a default parameter value of some value like None which a caller would never use. If the parameter has this default value, you know the caller did not specify the parameter. If the parameter has a non-default value, you know it came from the caller.
def my_func(mandatory_arg, optional_arg=100):
print(mandatory_arg, optional_arg)
http://docs.python.org/2/tutorial/controlflow.html#default-argument-values
I find this more readable than using **kwargs.
To determine if an argument was passed at all, I use a custom utility object as the default value:
MISSING = object()
def func(arg=MISSING):
if arg is MISSING:
...
def op(a=4,b=6):
add = a+b
print add
i)op() [o/p: will be (4+6)=10]
ii)op(99) [o/p: will be (99+6)=105]
iii)op(1,1) [o/p: will be (1+1)=2]
Note:
If none or one parameter is passed the default passed parameter will be considered for the function.
If you want give some default value to a parameter assign value in (). like (x =10). But important is first should compulsory argument then default value.
eg.
(y, x =10)
but
(x=10, y) is wrong
You can specify a default value for the optional argument with something that would never passed to the function and check it with the is operator:
class _NO_DEFAULT:
def __repr__(self):return "<no default>"
_NO_DEFAULT = _NO_DEFAULT()
def func(optional= _NO_DEFAULT):
if optional is _NO_DEFAULT:
print("the optional argument was not passed")
else:
print("the optional argument was:",optional)
then as long as you do not do func(_NO_DEFAULT) you can be accurately detect whether the argument was passed or not, and unlike the accepted answer you don't have to worry about side effects of ** notation:
# these two work the same as using **
func()
func(optional=1)
# the optional argument can be positional or keyword unlike using **
func(1)
#this correctly raises an error where as it would need to be explicitly checked when using **
func(invalid_arg=7)
Why does this piece of code throw a SyntaxError?
>>> def fun1(a="who is you", b="True", x, y):
... print a,b,x,y
...
File "<stdin>", line 1
SyntaxError: non-default argument follows default argument
While the following piece of code runs without visible errors:
>>> def fun1(x, y, a="who is you", b="True"):
... print a,b,x,y
...
All required parameters must be placed before any default arguments. Simply because they are mandatory, whereas default arguments are not. Syntactically, it would be impossible for the interpreter to decide which values match which arguments if mixed modes were allowed. A SyntaxError is raised if the arguments are not given in the correct order:
Let us take a look at keyword arguments, using your function.
def fun1(a="who is you", b="True", x, y):
... print a,b,x,y
Suppose its allowed to declare function as above,
Then with the above declarations, we can make the following (regular) positional or keyword argument calls:
func1("ok a", "ok b", 1) # Is 1 assigned to x or ?
func1(1) # Is 1 assigned to a or ?
func1(1, 2) # ?
How you will suggest the assignment of variables in the function call, how default arguments are going to be used along with keyword arguments.
>>> def fun1(x, y, a="who is you", b="True"):
... print a,b,x,y
...
Reference O'Reilly - Core-Python
Where as this function make use of the default arguments syntactically correct for above function calls.
Keyword arguments calling prove useful for being able to provide for out-of-order positional arguments, but, coupled with default arguments, they can also be used to "skip over" missing arguments as well.
SyntaxError: non-default argument follows default argument
If you were to allow this, the default arguments would be rendered useless because you would never be able to use their default values, since the non-default arguments come after.
In Python 3 however, you may do the following:
def fun1(a="who is you", b="True", *, x, y):
pass
which makes x and y keyword only so you can do this:
fun1(x=2, y=2)
This works because there is no longer any ambiguity. Note you still can't do fun1(2, 2) (that would set the default arguments).
Let me clear two points here :
firstly non-default argument should not follow default argument , it means you can't define (a=b,c) in function the order of defining parameter in function are :
positional parameter or non-default parameter i.e (a,b,c)
keyword parameter or default parameter i.e (a="b",r="j")
keyword-only parameter i.e (*args)
var-keyword parameter i.e (**kwargs)
def example(a, b, c=None, r="w" , d=[], *ae, **ab):
(a,b) are positional parameter
(c=none) is optional parameter
(r="w") is keyword parameter
(d=[]) is list parameter
(*ae) is keyword-only
(**ab) is var-keyword parameter
now secondary thing is if i try something like this :
def example(a, b, c=a,d=b):
argument is not defined when default values are saved,Python computes
and saves default values when you define the function
c and d are not defined, does not exist, when this happens (it exists only when the function is executed)
"a,a=b" its not allowed in parameter.
Required arguments (the ones without defaults), must be at the start to allow client code to only supply two. If the optional arguments were at the start, it would be confusing:
fun1("who is who", 3, "jack")
What would that do in your first example? In the last, x is "who is who", y is 3 and a = "jack".
I want to accept an argument with an equals sign in it:
my_nintendo_news = Website('https://mynintendonews.com', href = re.compile('https://mynintendonews.com/2018/'), "C:/Users/charl/Pictures/toad_small_60x60.png", "C:/Users/charl/Pictures/toad_small_60x60_bw.png" )
but I keep getting
SyntaxError: positional argument follows keyword argument
how can I avoid this? I need to use
href = re.compile('https://mynintendonews.com/2018/')
as an argument in another function, and I can't do that as a string (and I've heard using eval() is bad?)
You will need to pass optional arguments in the end and required arguments at the start.
In this case, I think href will be required argument, so here if you want to pass with argument name(in your case href) then you will need to pass all arguments with name and not one of them like "href ='example.com' ""
for e.g.
def test_method(a, b, c, d=0, e=0):
return a + b + c + d + e
for above method test_method, you cant call this function as test_method(1,b=2,3) , you will need to call it as test_method(1,2,3) or test_method(a=1, b=2, c=3)
But as "e" argument is optional argument you can call it as test_method(1,2,3, e=5) without bothering about value of d.
Have a look at the actual error message:
SyntaxError: positional argument follows keyword argument
You are calling Website and pass a positional argument, followed by a keyword argument, followed by two more positional arguments. Python does not allow this. Have a look at the Python Glossary for the explanation of positional and keyword arguments.
What you need to do is, either replace all positional arguments with keyword arguments or remove all keyword arguments (in your case: href=).
I'm not familiar with the code that you're using, so I'll make up some keyword arguments. This would be the case using only keyword arguments:
my_nintendo_news = Website(url='https://mynintendonews.com', href=re.compile('https://mynintendonews.com/2018/'), path1="C:/Users/charl/Pictures/toad_small_60x60.png", path2="C:/Users/charl/Pictures/toad_small_60x60_bw.png")
What you could also do is:
my_nintendo_news = Website(url='https://mynintendonews.com', href=re.compile('https://mynintendonews.com/2018/'), "C:/Users/charl/Pictures/toad_small_60x60.png", "C:/Users/charl/Pictures/toad_small_60x60_bw.png")
Here the last keyword argumenthref is followed by two more positional arguments.
I am learning about functions in python and found many good tutorials and answers about functions and their types, but I am confused in some places. I have read the following:
If function has "=" then it's a keyword argument i.e (a,b=2)
If function does not have "=" then it's positional argument i.e (a,b)
My doubts :
What is the meaning of a required argument and an optional argument? Is the default argument also a keyword argument? (since because both contain "=")
Difference between the positional, keyword, optional, and required
arguments?
python official documentation says that there are two types of arguments. If so, then what are *args and **kargs (I know how they work but don't know what they are)
how *args and **kargs store values? I know how *args and
**kargs works but how do they store values? Does *args store values in a tuple and **kargs in the dictionary?
please explain in deep. I want to know about functions because I am a newbie :)
Thanks in advance
Default Values
Let's imagine a function,
def function(a, b, c):
print a
print b
print c
A positional argument is passed to the function in this way.
function("position1", "position2", "position3")
will print
position1
position2
position3
However, you could pass in a keyword argument as below,
function(c="1",a="2",b="3")
and the output will become:
2
3
1
The input is no longer based on the position of the argument, but now it is based on the keyword.
The reason that b is optional in (a,b=2) is because you are giving it a default value.
This means that if you only supply the function with one argument, it will be applied to a. A default value must be set in the function definition. This way when you omit the argument from the function call, the default will be applied to that variable. In this way it becomes 'optional' to pass in that variable.
For example:
def function(a, b=10, c=5):
print a
print b
print c
function(1)
and the output will become:
1
10
5
This is because you didn't give an argument for b or c so they used the default values. In this sense, b and c are optional because the function will not fail if you do not explicitly give them.
Variable length argument lists
The difference between *args and **kwargs is that a function like this:
def function(*args)
for argument in args:
print argument
can be called like this:
function(1,2,3,4,5,6,7,8)
and all of these arguments will be stored in a tuple called args. Keep in mind the variable name args can be replaced by any variable name, the required piece is the asterisk.
Whereas,
def function(**args):
keys = args.keys()
for key in keys:
if(key == 'somethingelse'):
print args[key]
expects to be called like this:
function(key1=1,key2=2,key3=3,somethingelse=4,doesnt=5,matter=6)
and all of these arguments will be stored in a dict called args. Keep in mind the variable name args can be replaced by any variable name, the required piece is the double asterisk.
In this way you will need to get the keys in some way:
keys = args.keys()
Optional arguments are those that have a default or those which are passed via *args and **kwargs.
Any argument can be a keyword argument, it just depends on how it's called.
these are used for passing variable numbers of args or keyword args
yes and yes
For more information see the tutorial:
https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions
Why does this piece of code throw a SyntaxError?
>>> def fun1(a="who is you", b="True", x, y):
... print a,b,x,y
...
File "<stdin>", line 1
SyntaxError: non-default argument follows default argument
While the following piece of code runs without visible errors:
>>> def fun1(x, y, a="who is you", b="True"):
... print a,b,x,y
...
All required parameters must be placed before any default arguments. Simply because they are mandatory, whereas default arguments are not. Syntactically, it would be impossible for the interpreter to decide which values match which arguments if mixed modes were allowed. A SyntaxError is raised if the arguments are not given in the correct order:
Let us take a look at keyword arguments, using your function.
def fun1(a="who is you", b="True", x, y):
... print a,b,x,y
Suppose its allowed to declare function as above,
Then with the above declarations, we can make the following (regular) positional or keyword argument calls:
func1("ok a", "ok b", 1) # Is 1 assigned to x or ?
func1(1) # Is 1 assigned to a or ?
func1(1, 2) # ?
How you will suggest the assignment of variables in the function call, how default arguments are going to be used along with keyword arguments.
>>> def fun1(x, y, a="who is you", b="True"):
... print a,b,x,y
...
Reference O'Reilly - Core-Python
Where as this function make use of the default arguments syntactically correct for above function calls.
Keyword arguments calling prove useful for being able to provide for out-of-order positional arguments, but, coupled with default arguments, they can also be used to "skip over" missing arguments as well.
SyntaxError: non-default argument follows default argument
If you were to allow this, the default arguments would be rendered useless because you would never be able to use their default values, since the non-default arguments come after.
In Python 3 however, you may do the following:
def fun1(a="who is you", b="True", *, x, y):
pass
which makes x and y keyword only so you can do this:
fun1(x=2, y=2)
This works because there is no longer any ambiguity. Note you still can't do fun1(2, 2) (that would set the default arguments).
Let me clear two points here :
firstly non-default argument should not follow default argument , it means you can't define (a=b,c) in function the order of defining parameter in function are :
positional parameter or non-default parameter i.e (a,b,c)
keyword parameter or default parameter i.e (a="b",r="j")
keyword-only parameter i.e (*args)
var-keyword parameter i.e (**kwargs)
def example(a, b, c=None, r="w" , d=[], *ae, **ab):
(a,b) are positional parameter
(c=none) is optional parameter
(r="w") is keyword parameter
(d=[]) is list parameter
(*ae) is keyword-only
(**ab) is var-keyword parameter
now secondary thing is if i try something like this :
def example(a, b, c=a,d=b):
argument is not defined when default values are saved,Python computes
and saves default values when you define the function
c and d are not defined, does not exist, when this happens (it exists only when the function is executed)
"a,a=b" its not allowed in parameter.
Required arguments (the ones without defaults), must be at the start to allow client code to only supply two. If the optional arguments were at the start, it would be confusing:
fun1("who is who", 3, "jack")
What would that do in your first example? In the last, x is "who is who", y is 3 and a = "jack".