问题
I have two functions:
def f(a,b,c=g(b)):
blabla
def g(n):
blabla
c
is an optional argument in function f
. If the user does not specify its value, the program should compute g(b) and that would be the value of c
. But the code does not compile - it says name 'b' is not defined. How to fix that?
Someone suggested:
def g(b):
blabla
def f(a,b,c=None):
if c is None:
c = g(b)
blabla
But this doesn't work. Maybe the user intended c
to be None and then c
will have another value.
回答1:
def f(a,b,c=None):
if c is None:
c = g(b)
If None
can be a valid value for c
then you do this:
sentinel = object()
def f(a,b,c=sentinel):
if c is sentinel:
c = g(b)
回答2:
You cannot do it that way.
Inside the function, check if c is specified. If not, do the calculation.
def f(a,b,c=None):
if c == None:
c = g(b)
blabla
回答3:
value of c
will be evaluated (g(b)
) at compilation time. You need g
defined before f
therefore. And of course you need a global b
variable to be defined at that stage too.
b = 4
def g(a):
return a+1
def test(a, c=g(b)):
print(c)
test(b)
prints 5.
回答4:
The problem with
sentinel = object()
def f(a, b, c=sentinel):
if c is sentinel:
c = g(b)
is that sentinel
is global/public unless this code is part of a function/method. So someone might still be able to call f(23, 42, sentinel)
. However, if f
is global/public, you can use a closure to make sentinel
local/private so that the caller cannot use it:
def f():
sentinel = object()
def tmp(a, b, c=sentinel):
if c is sentinel:
c = g(b)
return tmp
f = f()
If you are concerned that static code analyzers could get the wrong idea about f
then, you can use the same parameters for the factory:
def f(a, b, c=object()): #@UnusedVariable
sentinel = object()
def tmp(a, b, c=sentinel):
if c is sentinel:
c = g(b)
return tmp
f = f(23, 42)
回答5:
def f(a,b,*args):
if len(args) == 1:
c = args[0]
elif len(args) == 0:
c = g(b)
else:
raise Exception('Function takes 2 or 3 parameters only.')
blabla
def g(n):
blabla
You can probably structure it better, but that's the main idea. Alternatively you can use **kwargs
and use the function like f(a,b,c=Something)
, you just have to modify f
accordingly.
Documentation
来源:https://stackoverflow.com/questions/1118454/non-standard-optional-argument-defaults