我想知道装饰函数是否有办法引用装饰器包装器创建的对象。当我想要使用装饰器时,我的问题出现了:
制作一个用子图创建图形的包装器
在包装器内执行装饰函数,这将添加一些图
最后将数字保存在包装器中
但是,修饰函数需要引用包装器创建的图形。装饰函数如何引用该对象?我们是否必须诉诸全局变量?
这是一个简短的例子,我在装饰函数中引用了一个在包装器中创建的变量(但是我没有设法在没有使用全局变量的情况下执行此操作):
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()
尽量避免使用全局变量。
使用参数将对象传递给函数
有一种规范的方法可以将值传递给函数:arguments。
调用包装器时,将对象作为参数传递给修饰函数。
from functools import wraps
def decorator(f):
obj = 1
@wraps(f)
def wrapper(*args):
return f(obj, *args)
return wrapper
@decorator
def func(x)
print(x)
func() # prints 1
使用默认参数传递同一对象
如果需要将相同的对象传递给所有函数,则将其存储为装饰器的默认参数是另一种选择。
from functools import wraps
def decorator(f, obj={}):
@wraps(f)
def wrapper(*args):
return f(obj, *args)
return wrapper
@decorator
def func(params)
params['foo'] = True
@decorator
def gunc(params)
print(params)
func()
gunc() # prints {'foo': True}
上面创建了一个公共私有dict,只能通过修饰函数访问。由于a dict是可变的,因此更改将反映在函数调用之间。
def declare_view(**kwds):
"""declaratively assocatiate a Django View function with resources
"""
def actual_decorator(func):
for k, v in kwds.items():
setattr(func, k, v)
return func
return actual_decorator
调用装饰器
@declare_view(
x=2
)
def decorated_func():
#the function can look at its own name, because the function exists
#by the time it gets called.
print("x in decorated_func:", decorated_func.x)
decorated_func()
产出
x in decorated_func: 2
在实践中,我已经使用了相当多的东西。我的想法是将Django视图函数与他们必须协作的特定后端数据类和模板相关联。因为它是声明性的,所以我可以通过所有Django视图进行内省并跟踪它们的相关URL以及自定义数据对象和模板。效果非常好,但是,该函数确实希望某些属性本身存在。它不知道装饰者设置它们。
哦,并且没有充分的理由,在我的情况下,这些变量在我的用例中作为参数传递,这些变量基本上保持硬编码值,这些值永远不会从函数的POV中改变。
一开始很奇怪,但非常强大,没有运行或维护缺点。
这是一些将其置于上下文中的实例。
@declare_view(
viewmanager_cls=backend.VueManagerDetailPSCLASSDEFN,
template_name="pssecurity/detail.html",
objecttype=constants.OBJECTTYPE_PERMISSION_LIST[0],
bundle_name="pssecurity/detail.psclassdefn",
)
def psclassdefn_detail(request, CLASSID, dbr=None, PORTAL_NAME="EMPLOYEE"):
"""
"""
f_view = psclassdefn_detail
viewmanager = f_view.viewmanager_cls(request, mdb, f_view=f_view)
...do things based on the parameters...
return viewmanager.HttpResponse(f_view.template_name)
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。