在python中将参数传递给装饰器 [英] Passing a parameter to the decorator in python

查看:280
本文介绍了在python中将参数传递给装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么带有参数的装饰器不起作用?

Why is this decorator with a parameter not working?

def decAny( f0 ):
    def wrapper( s0 ):
        return "<%s> %s </%s>" % ( any, f0(), any )
    return wrapper

@decAny( 'xxx' )
def test2():
    return 'test1XML'

print( test2() )

总是给我一个错误,说"str不可调用" 它正在尝试执行wrapper()中的返回字符串 而不是处理它并返回结果字符串

always gives me an error saying "str is not callable" it is trying to execute the return string inside the wrapper() instead of processing it and return the result string

推荐答案

装饰器是返回函数的函数.当将参数传递给装饰器"时,您实际上所做的是调用一个返回装饰器的函数.因此decAny()应该是一个返回一个函数的函数,该函数返回一个函数.

Decorators are functions that return functions. When "passing a parameter to the decorator" what you are actually doing is calling a function that returns a decorator. So decAny() should be a function that returns a function that returns a function.

它看起来像这样:

import functools

def decAny(tag):
    def dec(f0):
        @functools.wraps(f0)
        def wrapper(*args, **kwargs):
            return "<%s> %s </%s>" % (tag, f0(*args, **kwargs), tag)
        return wrapper
    return dec

@decAny( 'xxx' )
def test2():
    return 'test1XML'

示例:

>>> print(test2())
<xxx> test1XML </xxx>

请注意,除了解决您遇到的特定问题外,我还通过将*args**kwargs作为包装函数的参数并将它们传递给内部的f0调用,对代码进行了一些改进.装饰.这样一来,您就可以装饰一个可以接受任何数量的位置或命名参数的函数,并且该函数仍然可以正常工作.

Note that in addition to fixing the specific problem you were hitting I also improved your code a bit by adding *args and **kwargs as arguments to the wrapped function and passing them on to the f0 call inside of the decorator. This makes it so you can decorate a function that accepts any number of positional or named arguments and it will still work correctly.

您可以在此处阅读有关functools.wraps()的信息:
http://docs.python.org/2/library/functools.html#functools.wraps

You can read up about functools.wraps() here:
http://docs.python.org/2/library/functools.html#functools.wraps

这篇关于在python中将参数传递给装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆