简体   繁体   English

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

[英]“Push” attribute from decorator to decorated function in Python

Some basic question from beginner. 来自初学者的一些基本问题。 Is there a way to "push" attribute to a decorated function not using function arguments ? 有没有一种方法可以不使用函数参数将属性“推送”到装饰函数?

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())

Thanks in advance. 提前致谢。

Depending on whether you use Python 2 or 3 you can inject variables into the globals of a function like this: 根据您使用的是Python 2还是3,可以将变量注入到函数的globals ,如下所示:

Python 2 Python 2

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

Python 3 Python 3

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

If you set the attribute on new_func instead, you can access it simply as decorated_function.some_attr : 如果改为在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)

Otherwise, wraps makes the original function available as decorated_function.__wrapped__ in Python 3: 否则,自动wraps会使原始函数在Python 3中作为decorated_function.__wrapped__函数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)

In Python 2, the __wrapped__ is not set by wraps , so we need to set it up manually: 在Python 2中, __wrapped__不是通过wraps设置的,因此我们需要手动设置它:

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

However, this sounds like an XY problem; 但是,这听起来像是XY问题。 if you want to pass a value to the decorated_function you should let decorator_ pass it as an argument instead. 如果要将值传递给decorated_function ,则应让decorator_将其作为参数传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM