我有一个带有1个位置参数和2个关键字参数的函数:
def foo(arg1, kw_arg1='Keyword Argument', kw_arg2='Keyword Argument'):
print('The arguments are: {}, {}, {}'.format(arg1, kw_arg1, kw_arg2))
现在,我想要第二个关键字参数的默认值,即kw_arg2
依赖于kw_arg1
。更准确地说,我希望kw_arg2
的值默认为kw_arg1
,但不会传递给函数foo
。
该要求的函数原型将是:
def foo(arg1, kw_arg1='Keyword Argument', kw_arg2=kw_arg1):
print('The arguments are: {}, {}, {}'.format(arg1, kw_arg1, kw_arg2))
但是,这在Python 3.6.0上运行时会导致NameError
基本解决方案
我通过将我的函数定义为:
找到了解决方法def foo(arg1, kw_arg1='Keyword Argument', kw_arg2=None):
if kw_arg2 is None:
kw_arg2 = kw_arg1
print('The arguments are: {}, {}, {}'.format(arg1, kw_arg1, kw_arg2))
但是,我发现这个实现有点限制,因为我隐含在陈述kw_arg1
和kw_arg2
之间的关系。此外,我无法将kw_arg2
设置为None
。
我想知道如何通过更明确的解决方法实现这一目标。
答案 0 :(得分:0)
这样做的一种方法是使用**kwargs
,并要求用户在需要时为函数提供kw_arg2
作为关键字参数(即记录此!!)。
如果用户向None
提供kw_arg2
,则可以避免分崩离析。
这种方法的缺点是用户 提供kw_arg2
作为关键字参数,并且不能仅依赖于提供位置参数,而且它不太明显通过查看函数定义,函数需要什么参数。
def foo(arg1, kw_arg1='Keyword Argument', **kwargs):
"""A function that does foo.
Args:
arg1: ...
kw_arg1: ...
kw_arg2: Will default to the value of kw_arg1 if no
value is passed to this key word argument.
"""
if 'kw_arg2' in kwargs:
kw_arg2 = kwargs['kw_arg2']
else:
kw_arg2 = kw_arg1
print('The arguments are: {}, {}, {}'.format(arg1, kw_arg1, kw_arg2))
如果你希望用户也能够传递kw_arg2
作为位置参数,你可以尝试使用* args和** kwargs一些技巧,但当然这是你需要的东西小心并平衡潜在的滥用与利益:
def foo(arg1, kw_arg1='Keyword Argument', *args, **kwargs):
"""A function that does foo."""
if 'kw_arg2' in kwargs:
kw_arg2 = kwargs['kw_arg2']
elif args:
kw_arg2 = args[0]
else:
kw_arg2 = kw_arg1
print('The arguments are: {}, {}, {}'.format(arg1, kw_arg1, kw_arg2))