开发者社区> 问答> 正文

装饰函数有没有办法引用装饰器创建的对象?

我想知道装饰函数是否有办法引用装饰器包装器创建的对象。当我想要使用装饰器时,我的问题出现了:

制作一个用子图创建图形的包装器
在包装器内执行装饰函数,这将添加一些图
最后将数字保存在包装器中
但是,修饰函数需要引用包装器创建的图形。装饰函数如何引用该对象?我们是否必须诉诸全局变量?

这是一个简短的例子,我在装饰函数中引用了一个在包装器中创建的变量(但是我没有设法在没有使用全局变量的情况下执行此操作):

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

展开
收起
一码平川MACHEL 2019-01-23 16:17:45 1802 0
1 条回答
写回答
取消 提交回答
  • 尽量避免使用全局变量。

    使用参数将对象传递给函数
    有一种规范的方法可以将值传递给函数: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()

    proof that gunc receives the same object

    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)
    2019-07-17 23:26:42
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
对象的生命期管理 立即下载
建立联系方法之一 立即下载
继承与功能组合 立即下载