Decorators with arguments [duplicate]

拟墨画扇 提交于 2019-12-07 15:07:09

问题


Code as follows

def my_dec(func):
    def wrap(w):
        t = func(w)
        return t * 4
    return wrap


@my_dec
def testing(n):
    return n


new = testing(3)
print(new)  # This prints 12

This example is working fine, but now I'm trying to add the following to the decorator @my_dec(100), I need to multiply the given number by 100.

When I try this

@my_dec(100)
def testing(n):
    return n

I get the following error:

Traceback (most recent call last):
  File "./deco2", line 10, in <module>
    @my_dec(100)
  File "./deco2", line 5, in wrap
    t = func(w)
TypeError: 'int' object is not callable

How can I pass the 100 to the decorator?


回答1:


In the first example, you correctly define the decorator as a function which takes the wrapped function, and returns a new function.

To add arguments, you need to write a function which takes the arguments, and returns the decorator, i.e. returns the function which takes the wrapped function and returns a function.

One way to do it:

def my_dec(x):
    def dec(func):
        def wrap(w):
            t = func(w)
            return t * x
        return wrap
    return dec

This might be slightly clearer if you think about what the @ syntax expands to:

@my_dec(100)
def testing(n):
    return n

expands to:

def testing(n):
    return n
testing = my_dec(100)(testing)

Also, to reduce the high nesting level and make your decorator more readable and maintainable, you can define a decorator class instead, which takes its arguments in its __init__, and calls the wrapped function in its __call__. There are plenty of examples online. You can start by reading this question.

There are also ways to make your decorator take optional arguments (i.e. so that both your examples work).


And if you really want to understand decorators in depth, read Graham Dumpleton's blog. Highly recommended.



来源:https://stackoverflow.com/questions/25418499/decorators-with-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!