在Python3中,我可以做到(感谢pep 3102):
def some_fun(a, *args, log=None, verbose=0):
pass
并确保如果我将其称为:
some_fun(1, 2, 3, lob=debug_log)
我在意外关键字参数lob
上收到类型错误。
在Python2上,我无法在任意参数列表之后使用仅关键字参数定义some_fun()
。我必须这样做:
def some_fun(a, *args, **kw):
log = kw.get("log", None)
verbose = kw.get("verbose", 0)
当正确调用时,这可以正常工作,但是当我向some_fun()
提供一个或多个错误的关键字参数时,我希望得到类型错误,就像Python3一样。
答案 0 :(得分:2)
不是使用.get()
来检索值,而是使用.pop()
并在弹出所有仅关键字参数后检查kw
是否为空。
我使用了一个小辅助函数:
def check_empty_kwargs(kwargs):
import inspect
try:
keys = kwargs.keys()
assert len(keys) == 0
except AssertionError:
# uncomment if you want only one of the unexpected kwargs in the msg
# keys = keys[:1]
msg = "{0}() got an unexpected keyword argument{1} {2}".format(
inspect.stack()[1][3], # caller name
's' if len(keys) > 1 else '',
', '.join(["'{0}'".format(k) for k in keys]))
raise TypeError(msg)
你会像以下一样使用它:
def some_fun(a, *args, **kw):
log = kw.pop("log", None)
verbose = kw.pop("verbose", 0)
check_empty_kwargs(kw)
调用它(假定debug_log
已定义)
some_fun(1, 2, 3, lob=debug_log)
....
TypeError: some_fun() got an unexpected keyword argument 'lob'
回溯(当然)与Python3不同
答案 1 :(得分:1)
您可以检查允许的密钥,例如:
def f(a, *args, **kwargs):
surplus = set(kwargs).difference(('log', 'foo', 'bar'))
if surplus:
raise TypeError('got unexpected keyword argument(s): ' + ', '.join(surplus))
答案 2 :(得分:1)
如果您有许多处理步骤,您可以将上述技术与另一个技术结合起来:
def f(a, *args, **kwargs):
# we allow xyz, a, b
xyz = kwargs.pop('xyz', 1)
# now xyz must be gone, so we can only have a and/or b
others = (lambda a=1, b=2: (a, b)(**kwargs))
# either that was ok or it failed
return xyz, others