【问题标题】:Keyword arguments for function wrapped with decorator not working用装饰器包装的函数的关键字参数不起作用
【发布时间】:2019-03-15 02:27:05
【问题描述】:

我在装饰器上找到的所有教程都建议在包装函数的签名中使用 *args, **kwargs 来处理来自包装函数的参数。然而 kwargs 不起作用,而普通的 args 是:

from functools import wraps


def wrapper(a_thing):
    @wraps(a_thing)
    def do_thing(*args, **kwargs):
        print('before')
        print(kwargs)
        value = a_thing(*args, **kwargs)
        print("after", *args, **kwargs)
        return value
    return do_thing


@wrapper
def output(*args, **kwargs):
    print('during', *args, **kwargs)

import pdb; pdb.set_trace()

这是我的交互式输出:

(Pdb) output(99, 100)
before
{}
during 99 100
after 99 100
(Pdb) output(arg1=99, arg2=100)
before
{'arg1': 99, 'arg2': 100}
*** TypeError: 'arg1' is an invalid keyword argument for this function
(Pdb)

这是许多此类教程之一的an example

如果它不起作用,使用 **kwargs 有什么意义?我觉得我错过了什么。

【问题讨论】:

    标签: python


    【解决方案1】:

    您不想解开对print 的调用; print 只接受有限数量的关键字参数,并将拒绝所有其他参数。大概你只是想看看传递了什么,所以打印原始的 tupledict 而不拆包:

    def wrapper(a_thing):
        @wraps(a_thing)
        def do_thing(*args, **kwargs):
            print('before')
            print(kwargs)
            value = a_thing(*args, **kwargs)
            print("after", args, kwargs)  # Removed unpacking
            return value
        return do_thing
    
    
    @wrapper
    def output(*args, **kwargs):
        print('during', args, kwargs)  # Removed unpacking
    

    解包的重点在于它将 * 解包可迭代的元素作为顺序位置参数传递,** 解包映射中的键值对使用键作为关键字参数,并将值作为关联的价值。所以当你这样做时:

        print('during', *args, **kwargs)
    

    output(arg1=99, arg2=100) 调用函数后,就好像你跑了:

        print('during', arg1=99, arg2=100)
    

    arg1arg2 都不是 print 接受的关键字,所以它对你尖叫。通过去掉解包,print 就相当于:

        print('during', (), {'arg1': 99, 'arg2': 100})
    

    这是完全有效的(它直接打印tupledict,而不是试图解包)。

    【讨论】:

    • 啊,谢谢,错误中提到的“函数”是print()函数,而不是我假设的output函数.....哇。
    猜你喜欢
    • 2011-06-25
    • 2023-04-03
    • 2014-10-04
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2018-05-24
    • 1970-01-01
    相关资源
    最近更新 更多