【问题标题】:Decorate methods per instance in Python在 Python 中为每个实例装饰方法
【发布时间】:2011-06-15 11:16:33
【问题描述】:

假设我有一些简单的课程

class TestClass:
    def doSomething(self):
        print 'Did something'

我想装饰doSomething方法,例如统计调用次数

class SimpleDecorator(object):
    def __init__(self,func):
        self.func=func
        self.count=0
    def __get__(self,obj,objtype=None):
        return MethodType(self,obj,objtype)
    def __call__(self,*args,**kwargs):
        self.count+=1
        return self.func(*args,**kwargs)

现在这计算了对装饰方法的调用次数,但是我希望有每个实例的计数器,这样之后

foo1=TestClass()
foo1.doSomething()
foo2=TestClass()

foo1.doSomething.count 是 1,foo2.doSomething.count 是 0。据我了解,这是不可能使用装饰器的。有没有办法实现这种行为?

【问题讨论】:

    标签: python decorator


    【解决方案1】:

    利用self(即调用方法的对象)作为参数传递给方法的事实:

    import functools
    
    def counted(method):
        @functools.wraps(method)
        def wrapped(obj, *args, **kwargs):
            if hasattr(obj, 'count'): 
                obj.count += 1
            else:
                obj.count = 1
            return method(obj, *args, **kwargs)
        return wrapped
    

    在上面的代码中,我们截取了对象作为修饰版本方法的obj参数。装饰器的使用非常简单:

    class Foo(object):
        @counted
        def do_something(self): pass
    

    【讨论】:

      【解决方案2】:

      *args 的第一个元素不会是调用该方法的对象吗?你不能把计数存储在那里吗?

      【讨论】:

      • 是的,我想这是可能的。但这对我来说感觉像是次优设计,因为装饰器将依赖于它所使用的类的属性,从而使其更难使用。
      猜你喜欢
      • 2010-12-12
      • 2012-04-21
      • 2013-06-23
      • 2013-02-12
      • 2013-02-03
      • 2011-03-23
      • 2014-05-31
      • 2020-10-15
      相关资源
      最近更新 更多