[sample.py]
def f(name='Hello Guest'):
print(name)
def A(name=None):
f(name)
A()
Expected Output: 'Hello Guest'
Current Output: None
I'm expecting the answers by without using much more codes like 'name = name if name is not None else some_default_value'
Thanks in advance!
-
Instead of the default argument you can have a check inside method and assign default value.Sid– Sid2019年01月18日 06:39:18 +00:00Commented Jan 18, 2019 at 6:39
5 Answers 5
Does this work for you?
def f(name):
print(name or 'Hello Guest')
def A(name=None):
f(name)
A()
Out: "Hello Guest"
A("Hello World")
Out: "Hello World"
If the name variable is being used multiple times in the function, you could just reassign it in the beginning of the function. name = name or "Hello Guest"
6 Comments
0?bool('0') is still True. Hence, print(name or '0') should work.A(0). Also certain times, empty arrays and other "Falsy" variables will lead to printing Hello Guest instead. Of course in such a straightforward example you wouldn't put an empty list in, but you can easily image that this pattern (antipattern!) will unexpectedly break your application!The best way to do this will be to use a shared default:
DEFAULT_NAME = "Hello Guest"
def f(name=DEFAULT_NAME):
print(name)
def A(name=DEFAULT_NAME):
f(name)
1 Comment
Using inspect.signature to store default is one way to go:
def f(name='Hello Guest'):
print(name or inspect.signature(f).parameters['name'].default)
def A(name=None):
f(name)
A()
# Hello Guest
With some loss of generality, but simpler (shorter and no other lib):
def f(name='Hello Guest'):
print(name or f.__default__[0])
def A(name=None):
f(name)
A()
# Hello Guest
I have been in a similar situation where I can't change the signature or the body of a function I call internally but I want to use the defaults or pass arguments only when they exists(which can get tricky if you plan to pop those keys manually)
This was the cleanest and the most reusable solution I could write.
Simplest solution:
def f(name='Hello Guest'):
print(name)
def A(**kwargs):
# If kwargs has any keys which are None in value, will be removed.
# Keys which don't exists in kwargs won't propagate, hence using default value.
f(**{k:v for k, v in kwargs.items() if v})
A()
# This returns "Hello Guest"
A(**{"name": None})
# This returns "Hello Guest"
A(**{"name": "Someone!"})
# This returns "Someone!"
Inspect solution:
Inspect is a great module if you plan to do something complex with function signature, parameters, etc.
from inspect import signature
# This function is untouched
def f(name='Hello Guest'):
print(name)
# changed the signature so that params can propagate further
def A(**kwargs):
t = signature(f, follow_wrapped=True)
# If kwargs has any key which is None in value,
# it will be replaced with default values for the function.
# Keys which don't exists in kwargs won't propagate.
f(**{k: (v or t.parameters[k].default) for k, v in kwargs.items()})
A()
# This returns "Hello Guest"
A(**{"name": None})
# This returns "Hello Guest"
A(**{"name": "Someone!"})
# This returns "Someone!"
1 Comment
Or
def f(name):
print(name)
def A(name = 'Hello Guest'):
f(name)
A()
3 Comments
f should have a default argument. Your answer... contradicts this.