【问题标题】:Why can I pass a list of named arguments -- but not unnamed arguments -- to this decorator?为什么我可以将命名参数列表(而不是未命名参数)传递给这个装饰器?
【发布时间】:2017-06-06 20:21:02
【问题描述】:

此问题与How pass unknown list of unnamed arguments to a python decorator? 不重复。我在这里提出了一个不同但相关的问题。

我创建了一个 python 装饰器my_decorator 方法,如下所示。我希望这个装饰器接受未知的参数列表:

#!/usr/bin/env python
from functools import wraps

class A:
    def my_decorator(self, func=None, *args, **kwargs):
        print "Hello World2!"
        print 'args = {}'.format(args)
        print 'kwargs = {}'.format(kwargs)
        def inner_function(decorated_function):
            def wrapped_func(*fargs, **fkwargs):
                print "Hello World3!"
                return decorated_function(*fargs, **fkwargs)
            return wrapped_func

        if func:
            return inner_function(func)
        else:
            return inner_function

class B:
    my_a = A()

    @my_a.my_decorator(a1="Yolo", b1="Bolo")
    def my_func(self):
         print "Hello World1!"

my_B = B()
my_B.my_func()

这段代码运行良好:

Hello World2!
args = ()
kwargs = {'a1': 'Yolo', 'b1': 'Bolo'}
Hello World3!
Hello World1!

但是,现在,我不想将命名参数传递给@my_a.my_decorator,而是像这样传递未命名参数:@my_a.my_decorator('Yolo', 'Bolo'),但它失败了:

Hello World2!
args = ('Bolo',)
kwargs = {}
Hello World3!
Traceback (most recent call last):
  File "./decorator_test.py", line 20, in <module>
    class B:
  File "./decorator_test.py", line 23, in B
    @my_a.my_decorator('Yolo', 'Bolo')
  File "./decorator_test.py", line 12, in wrapped_func
    return decorated_function(*fargs, **fkwargs)
TypeError: 'str' object is not callable

我该如何解决这个问题?

【问题讨论】:

  • 您将 'Yolo' 作为 func 参数传递。
  • 这与装饰器无关......所有功能都以这种方式工作。本质上,如果您有关键字参数,则可以使用名称或位置传递它。你想要一个keyword only argument。你的签名应该是:def my_decorator(self, *args, func=None, **kwargs)
  • 为什么装饰器甚至是一种方法?它从不使用self 做任何事情。
  • 装饰器是这里的红鲱鱼。真正的问题是函数参数。

标签: python decorator python-decorators


【解决方案1】:
def my_decorator(self, *args, **kwargs):
    [skip]
    if 'func' in kwargs:
        return inner_function(kwargs.pop('func'))
    else:
        return inner_function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-29
    • 2014-08-12
    • 2020-02-09
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 2014-11-17
    • 2013-04-08
    相关资源
    最近更新 更多