I want to define a function with some optional arguments, let's say A (mandatory) and B (optional). When B is not given, I want it to take the same value as A. How could I do that?
I have tried this, but it doesn't work (name 'B' is not defined):
def foo(A, B=A):
do_something()
I understand that the values of the arguments are not assigned before the body of the function.
You shall do this inside of your function.
Taking your original function:
def foo(A, B=A):
do_something()
try something like:
def foo(A, B=None):
if B is None:
B = A
do_something()
Important thing is, that function default values for function arguments are given at the time, the function is defined.
When you call the function with some value for A, it is too late as the B default value was already assigned and lives in function definition.
You could do it like this. If B has a value of None then assign it from A
def foo(A, B=None):
if B is None:
B = A
print 'A = %r' % A
print 'B = %r' % B
Related
I'm trying to use
def my_function(a,b)
If I try to print function like this
print(my_function()), when values start from none, I get
"missing 2 required positional arguments"
I want to use default value so when I use, print(my_function()),
a=10 and b=a.
So I tried
def my_function(a=10,b=a)
and I got a not defined.
I don't want to define a before with global.
Is it possible? or something like this
def my_function(a,b)
if a == None:
a = 10
if b == None:
b = a
This didn't work either when I used print(my_function()).
You can set the default to None:
def my_function(a=10, b=None):
if b is None:
b = a
Here the default for a is 10, and b is set to a if left to the default value.
If you need to accept None as well, pick a different, unique default to act as a sentinel. An instance of object() is an oft-used convention:
_sentinel = object()
def my_function(a=10, b=_sentinel):
if b is _sentinel:
b = a
Now you can call my_function(11, None) and b will be set to None, call it without specifying b (e.g. my_function() or my_function(42), and b will be set to whatever a was set to.
Unless a parameter has a default (e.g. is a keyword parameter), they are required.
This function my_function(a,b) expected two positional arguments without default value so It can't be called without them passed
So the main question how can we pass two argument so that second is set to first if not passed
There are two way for this:
kwargs unpacking
def my_function(a=10, **kwargs):
b = kwargs.get('b', a)
sentinel as default Value
_sentinel = object()
def my_function(a=10, b=_sentinel):
if b is _sentinel:
b = a
Hum! I thing you can't define my_function like this. But you can use a decorator to hide the default values computation.
For example:
import functools
def my_decorator(f):
#functools.wraps(f)
def wrapper(a=10, b=None):
if b is None:
b = a
return f(a, b)
return wrapper
You can then define your function like this:
#my_decorator
def my_function(a, b):
return (a, b)
You can use your function with zero, one or two parameters:
>>> print(my_function())
(10, 10)
>>> print(my_function(5))
(5, 5)
>>> print(my_function(5, 12))
(5, 12)
Let's say we have the function f and I need the argument b to default to an empty list, but can't set b=[] because of the issue around mutable default args.
Which of these is the most Pythonic, or is there a better way?
def f(a, b=None):
if not b:
b = []
pass
def f(a, b=None):
b = b or []
pass
The first form as it reads easier. Without any specific context, you should explicitly test for the default value, to avoid potential truthiness issues with the passed in value.
def f(a, b=None):
if b is None:
b = []
pass
From PEP 8, Programming Recommendations:
Also, beware of writing if x when you really mean if x is not None --
e.g. when testing whether a variable or argument that defaults to None
was set to some other value. The other value might have a type (such
as a container) that could be false in a boolean context!
You can see examples of this approach throughout the cpython repository:
Lib/bdb.py
Lib/argparse.py
Lib/base64.py
def f(a, b=''):
if not b:
b = []
print(a)
You can cdo something simple such as "if not b". If you are going to make the default argument an empty string or set it equal to None, you can simply use an if statement to define what B should be if you are never actually going to enter an argument for b. In this example we simply set it to an empty list.
Lets say I have the following function:
def myFun(a=None, b=None):
print a, b
Now I call the function:
myFun("hi") # Case 1
>>>hi None
myFun(b="hi") # Case 2
>>>None hi
myFun(a="hi") # Case 3
>>>hi None
Is there a way to throw an exception if the function caller did not decide which variable the value "hi" is assigned to? That means I would like to have an exception in the 1st case but not in the 2nd and 3rd case. I use python 2.7.
In Python3 you can specify keyword-only arguments:
def myFun(*, a=None, b=None):
print(a, b)
myFun('hi')
raises
TypeError: myFun() takes 0 positional arguments but 1 was given
In Python2, as Ricardo Silveira points out you could use **kwargs to force all arguments to be keyword arguments.
def myFun(**kwargs):
a, b = kwargs.get('a'), kwargs.get('b')
print(a, b)
myFun('hi')
# TypeError: myFun() takes exactly 0 arguments (1 given)
def my_fun(**kwargs):
a = kwargs.get("a", None)
b = kwargs.get("b", None)
# have your code here...
Then: my_fun("hi") shouldn't work...
You can actually allow the user to provide any arguments they'd like by using **kwargs.
def myFun(**kwargs):
print kwargs[a]
print kwargs[b]
This will cause an error if a or b aren't defined, but they're not very helpful.
You can make your own errors by checking if the value exists. For example:
def myFun(**kwargs):
if not kwargs.get(a):
raise Exception('a is not here!')
if not kwargs.get(b):
raise Exception ('b is not here!')
print kwargs[a], kwargs[b]
I'm trying to use
def my_function(a,b)
If I try to print function like this
print(my_function()), when values start from none, I get
"missing 2 required positional arguments"
I want to use default value so when I use, print(my_function()),
a=10 and b=a.
So I tried
def my_function(a=10,b=a)
and I got a not defined.
I don't want to define a before with global.
Is it possible? or something like this
def my_function(a,b)
if a == None:
a = 10
if b == None:
b = a
This didn't work either when I used print(my_function()).
You can set the default to None:
def my_function(a=10, b=None):
if b is None:
b = a
Here the default for a is 10, and b is set to a if left to the default value.
If you need to accept None as well, pick a different, unique default to act as a sentinel. An instance of object() is an oft-used convention:
_sentinel = object()
def my_function(a=10, b=_sentinel):
if b is _sentinel:
b = a
Now you can call my_function(11, None) and b will be set to None, call it without specifying b (e.g. my_function() or my_function(42), and b will be set to whatever a was set to.
Unless a parameter has a default (e.g. is a keyword parameter), they are required.
This function my_function(a,b) expected two positional arguments without default value so It can't be called without them passed
So the main question how can we pass two argument so that second is set to first if not passed
There are two way for this:
kwargs unpacking
def my_function(a=10, **kwargs):
b = kwargs.get('b', a)
sentinel as default Value
_sentinel = object()
def my_function(a=10, b=_sentinel):
if b is _sentinel:
b = a
Hum! I thing you can't define my_function like this. But you can use a decorator to hide the default values computation.
For example:
import functools
def my_decorator(f):
#functools.wraps(f)
def wrapper(a=10, b=None):
if b is None:
b = a
return f(a, b)
return wrapper
You can then define your function like this:
#my_decorator
def my_function(a, b):
return (a, b)
You can use your function with zero, one or two parameters:
>>> print(my_function())
(10, 10)
>>> print(my_function(5))
(5, 5)
>>> print(my_function(5, 12))
(5, 12)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get the original variable name of variable passed to a function
Is there something like below in python where based on the name of the parameter passed to a function we can execute conditional statements like below.
def func(a,b,c,d)
if fourth paramter = d:
#code
elif fourth parameter = e:
#code
else:
#code
def main():
func(a,b,c,d)
func(a,b,c,e)
You should use keyword arguments:
def func(a, b, c, **kwargs):
if 'd' in kwargs:
....
elif 'c' in kwargs:
....
This is not exactly equivalent to what you want, though. If you want to ensure that d or e is the fourth parameter, that would be more troublesome.
Then you could try something like:
def func(a, b, c, d=None, e=None):
if d is not None and e is None:
....
elif e is not None and d is None:
....
Note that this is not exactly what you're asking. It will not access the "original" name of the variable passed to the function as a positional argument, as in the question linked by Stuart. You shouldn't even try to do that, it's pointless.
kwargs will not give you exactly what you want, but it can be close:
def func(a, b, c, **kwargs):
if 'd' in kwargs:
print "do something"
elif 'e' in kwargs:
print "do something else"
def main():
func(a = 1 ,b = 2 ,c = 3, d = 'some_value')
func(a = 1 ,b = 2 ,c = 3, e = 'some_value')