【发布时间】:2019-06-16 09:31:52
【问题描述】:
我想知道装饰函数是否可以引用由装饰器的包装器创建的对象。当我考虑使用装饰器时,我的问题出现了:
- 制作一个包装器,用于创建带有子图的图形
- 在包装器内部执行装饰函数,该函数将添加一些图
- 最终将图形保存在包装器中
但是,装饰函数需要引用包装器创建的图形。装饰函数如何引用该对象?我们是否必须求助于全局变量?
这是一个简短的示例,我在装饰函数中引用了一个在包装器中创建的变量(但如果不使用全局变量进行调整,我就无法做到这一点):
def my_decorator(func):
def my_decorator_wrapper(*args, **kwargs):
global x
x = 0
print("x in wrapper:", x)
return func(*args, **kwargs)
return my_decorator_wrapper
@my_decorator
def decorated_func():
global x
x += 1
print("x in decorated_func:", x)
decorated_func()
# prints:
# x in wrapper: 0
# x in decorated_func: 1
我知道这在课堂上很容易做到,但我出于好奇提出这个问题。
【问题讨论】:
-
装饰器可以在调用包装函数时为其提供附加参数。通常这是一个坏主意,因为装饰是您可以可选地对函数执行的操作,但您所讨论的场景是装饰器和装饰器之间的耦合比正常情况要紧密得多。
-
在 Python 3 中,您可以使用
nonlocal来引用已知由装饰器创建的对象。 -
@user2357112 好的,对。我对闭包和动态范围感到困惑。
-
能否加个代码sn-p让你的请求更清晰?
-
有多种方法可以实现,但似乎没有一种特别好,而且真的,如果你的装饰函数需要了解装饰器的内部结构,它可能不是一个好的用例装饰器开始