防止变量关键字参数中的拼写错误
prevent typos in variable keyword args
在Python3我可以做到(感谢pep 3102):
def some_fun(a, *args, log=None, verbose=0):
pass
并确保如果我调用它:
some_fun(1, 2, 3, lob=debug_log)
我在意外关键字参数 lob
上收到类型错误。
On Python2 我无法在任意参数列表后使用仅关键字参数定义 some_fun()
。我必须做:
def some_fun(a, *args, **kw):
log = kw.get("log", None)
verbose = kw.get("verbose", 0)
正确调用时一切正常,但我想在向 some_fun()
提供一个或多个错误的关键字参数时得到类型错误,就像 Python3 一样。
不使用 .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
不同
您可以检查允许的密钥,例如:
def f(a, *args, **kwargs):
surplus = set(kwargs).difference(('log', 'foo', 'bar'))
if surplus:
raise TypeError('got unexpected keyword argument(s): ' + ', '.join(surplus))
如果您有一堆处理步骤,可以将上述技术与另一种技术结合使用:
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
在Python3我可以做到(感谢pep 3102):
def some_fun(a, *args, log=None, verbose=0):
pass
并确保如果我调用它:
some_fun(1, 2, 3, lob=debug_log)
我在意外关键字参数 lob
上收到类型错误。
On Python2 我无法在任意参数列表后使用仅关键字参数定义 some_fun()
。我必须做:
def some_fun(a, *args, **kw):
log = kw.get("log", None)
verbose = kw.get("verbose", 0)
正确调用时一切正常,但我想在向 some_fun()
提供一个或多个错误的关键字参数时得到类型错误,就像 Python3 一样。
不使用 .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
不同您可以检查允许的密钥,例如:
def f(a, *args, **kwargs):
surplus = set(kwargs).difference(('log', 'foo', 'bar'))
if surplus:
raise TypeError('got unexpected keyword argument(s): ' + ', '.join(surplus))
如果您有一堆处理步骤,可以将上述技术与另一种技术结合使用:
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