decorator to count the call

class decorator:

class tracer0:
    def __init__(self, func):
        self.calls = 0
        self.func = func
    def __call__(self, *args):
        self.calls += 1
        print("call %s to %s" % (self.calls, self.func.__name__))
        return self.func(*args)

function decorator:
1. use function attribute

def tracer(func):
    def oncall(*args):
        oncall.calls += 1        
        print('call %s to %s' % (oncall.calls, func.__name__))        
        return func(*args)    
    oncall.calls = 0    
    return oncall
  1. use nonlocal
def tracer1(func):
    count = 0
    def __decorator(*args, **kargs):
        nonlocal count
        count += 1
        print('call %s to %s' % (count, func.__name__))
        return func(*args, **kargs)
    return __decorator

class decorator could act like a proxy that could intercept attribute access to wrapped class.

def class_wrapper(cls):
    class Proxy:
        def __init__(self, *args):
            self.__wrapped = cls(*args)
        def __getattr__(self, name):
            return getattr(self.__wrapped, name)
    return Proxy

@class_wrapper
class Person:
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return self.name

p1 = Person('alice')
print(p1)
print(p1.__class__)

python2 result:

alice
__main__.Proxy

python3 result:

<__main__.class_wrapper.<locals>.Proxy object at 0x7f6e501a03c8>
<class '__main__.class_wrapper.<locals>.Proxy'>

Why, because implicit attribute fetch starts at class level in python3.x while at instance level in python2.x.
One thing to be clear is __getattr__, from python doc:

object.__getattr__(self, name)
Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance
attribute nor is it found in the class tree for self). name is the attribute name. This method should return 
the (computed) attribute value or raise an AttributeError exception.

__getattr__ only be called under two conditions:
1. when fetch attribute in an instance
2. the attribute cannot be found(in instance and in MRO)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值