从装饰器“推”属性到Python中的装饰函数

时间:2016-08-30 09:55:58

标签: python decorator

初学者的一些基本问题。有没有办法将属性“推”到一个不使用函数参数的装饰函数?

import sys
from functools import wraps


def decorator_(func):
    @wraps(func)
    def newfunc():
        func.some_attr = 'some_attr'
        func()
    return newfunc

@decorator_
def decorated_function():
    # ??? access some_attr ???
    print some_attr

def main():
    decorated_function()

if __name__ == '__main__':
    sys.exit(main())

提前致谢。

2 个答案:

答案 0 :(得分:0)

根据您使用的是Python 2还是3,您可以将变量注入到这样的函数的globals中:

Python 2

func.func_globals["some_attr"] = "some_value"

Python 3

func.__globals__["some_attr"] = "some_value"

答案 1 :(得分:0)

如果您在new_func上设置属性,则可以将其作为decorated_function.some_attr访问:

def decorator_(func):
    @wraps(func)
    def newfunc():
        newfunc.some_attr = 'some_attr'
        func()
    return newfunc

@decorator_
def decorated_function():
    print(decorated_function.some_attr)

否则,wraps使原始函数在Python 3中可用为decorated_function.__wrapped__

def decorator_(func):
    @wraps(func)
    def newfunc():
        func.some_attr = 'some_attr'
        func()
    return newfunc

@decorator_
def decorated_function():
    print(decorated_function.__wrapped__.some_attr)

在Python 2中,__wrapped__未由wraps设置,因此我们需要手动设置:

def decorator_(func):
    @wraps(func)
    def newfunc():
        func.some_attr = 'some_attr'
        func()
    newfunc.__wraps__ = func
    return newfunc

然而,这听起来像一个XY问题;如果您想将值传递给decorated_function,您应该让decorator_将其作为参数传递。