考虑一个带有签名f(a, b)
的函数。将来,我想将签名更改为 f(a, *, b)
,不允许将 b 作为位置参数传递。
为了减少更改的影响,我想首先反对在位置上指定 b,警告这样做的用户。
为此我想写这样的东西:
def f(a, b):
frame = inspect.currentframe()
if b in frame.specified_as_positional:
print('Do not do that')
else:
print('Good')
结果是
>>> f(1, 2)
'Do not do that'
>>> f(1, b=2)
'Good'
inspect.getargvalues(frame)
似乎还不够。 ArgInfo 对象只是提供
>>> f(1,b=2)
ArgInfo(args=['a', 'b'], varargs=None, keywords=None, locals={'a': 1, 'b': 2})
在 Python 中甚至可以进行这种检查吗?从概念上讲,解释器似乎不需要记住参数是按位置指定还是作为关键字指定。
Python 2 支持会很好,但不是严格要求的。
最佳答案
您可以使用包装器在用户和函数之间添加一个额外的步骤。在该步骤中,您可以在名称重要之前检查参数。请注意,这取决于 b
没有默认值并且始终必须作为 arg 给出的事实。
functools.wraps
用于使修饰后的函数在很多方面类似于原始函数。
import functools
import warnings
def deprecate_positional(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
if 'b' not in kwargs:
warnings.warn(
'b will soon be keyword-only',
DeprecationWarning,
stacklevel=2
)
return fun(*args, **kwargs)
return wrapper
@deprecate_positional
def f(a, b):
return a + b
>>> f(1, b=2)
3
>>> f(1, 2)
Warning (from warnings module):
File "C:/Users/nwerth/Desktop/deprecate_positional.py", line 36
print(f(1, 2))
DeprecationWarning: b will soon be keyword-only
3
关于python - 检查参数是按位置还是通过关键字传递的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56468082/