相关疑难解决方法(0)

Python装饰器的最佳实践,使用类vs函数

正如我所理解的那样,有两种方法可以做Python装饰器,既可以使用__call__类,也可以定义函数作为装饰器.这些方法的优点/缺点是什么?有一种首选方法吗?

例1

class dec1(object):
    def __init__(self, f):
        self.f = f
    def __call__(self):
        print "Decorating", self.f.__name__
        self.f()

@dec1
def func1():
    print "inside func1()"

func1()

# Decorating func1
# inside func1()
Run Code Online (Sandbox Code Playgroud)

例2

def dec2(f):
    def new_f():
        print "Decorating", f.__name__
        f()
    return new_f

@dec2
def func2():
    print "inside func2()"

func2()

# Decorating func2
# inside func2()
Run Code Online (Sandbox Code Playgroud)

python decorator syntactic-sugar python-2.7

53
推荐指数
3
解决办法
2万
查看次数

Python中的Decorator类

我想构造用作装饰器的类,原则如下:

  1. 应该可以在top off 1函数上堆叠多个这样的类装饰器.
  2. 生成的函数名称指针应该与没有装饰器的同一函数无法区分,可以保存它的类型/类.
  3. 除非装饰者实际要求,否则对装饰器进行排序不应该是相关的.IE浏览器.独立装饰者可以按任何顺序应用.

这是一个Django项目,我正在处理的具体情况现在该方法需要2个装饰器,并显示为普通的python函数:

@AccessCheck
@AutoTemplate
def view(request, item_id) {}
Run Code Online (Sandbox Code Playgroud)

@AutoTemplate更改了函数,以便它不返回HttpResponse,而只返回一个字典以供在上下文中使用.使用RequestContext,并从方法名称和模块推断模板名称.

@AccessCheck根据item_id添加对用户的附加检查.

我猜这只是为了让构造函数正确并复制适当的属性,但这些属性是什么?

以下装饰器不会像我描述的那样工作:

class NullDecl (object):
    def __init__ (self, func):
        self.func = func
    def __call__ (self, * args):
        return self.func (*args)
Run Code Online (Sandbox Code Playgroud)

如以下代码所示:

@NullDecl
@NullDecl
def decorated():
    pass

def pure():
    pass

# results in set(['func_closure', 'func_dict', '__get__', 'func_name',
# 'func_defaults', '__name__', 'func_code', 'func_doc', 'func_globals'])
print set(dir(pure)) - set(dir(decorated));
Run Code Online (Sandbox Code Playgroud)

此外,尝试添加"打印FUNC.名称在NullDecl构造函数,它会为第一个装饰工作,而不是第二个" -正如名字将会丢失.

精致的eduffy的回答有点,而且看起来效果很好:

class NullDecl (object):
    def __init__ (self, func):
        self.func = func
        for n …
Run Code Online (Sandbox Code Playgroud)

python decorator

38
推荐指数
3
解决办法
2万
查看次数

如何用装饰器类装饰实例方法?

考虑这个小例子:

import datetime as dt

class Timed(object):
    def __init__(self, f):
        self.func = f

    def __call__(self, *args, **kwargs):
        start = dt.datetime.now()
        ret = self.func(*args, **kwargs)
        time = dt.datetime.now() - start
        ret["time"] = time
        return ret

class Test(object):
    def __init__(self):
        super(Test, self).__init__()

    @Timed
    def decorated(self, *args, **kwargs):
        print(self)
        print(args)
        print(kwargs)
        return dict()

    def call_deco(self):
        self.decorated("Hello", world="World")

if __name__ == "__main__":
    t = Test()
    ret = t.call_deco()
Run Code Online (Sandbox Code Playgroud)

打印

Hello
()
{'world': 'World'}
Run Code Online (Sandbox Code Playgroud)

为什么self参数(应该是Test obj实例)不作为第一个参数传递给装饰函数decorated

如果我手动完成,例如:

def call_deco(self):
    self.decorated(self, "Hello", …
Run Code Online (Sandbox Code Playgroud)

python class self python-decorators

32
推荐指数
2
解决办法
1万
查看次数