python - 检查参数是按位置还是通过关键字传递的

标签 python python-3.x

考虑一个带有签名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/

相关文章:

python - spidev/Python 错误

python - 如何在 Python 中递归尝试不同的 SSH 密码?

python - 使用 Flask 显示 matplotlib 图

python - 在 telethon.events 中使用 "chats"参数

python-3.x - Python 3 - 多个 AsyncIO 连接

python - 将mysql中的2个数据字段与python进行比较

python - Tensorflow:使用更多不同矩阵进行张量乘法

python - 如何将Qt图形场景项保存在文件中并再次打开它?

python - 该元素的值与附加到列表中的值不同

python - 在 Django 管理中内联 : has no ForeignKey