python class decorator

提问在注释里

def object_counter(class_):
    class_.__getattr__orig = class_.__getattribute__#class_.__getattribute__是一个method, 这里是赋值给变量的意思?

    def new_getattr(self, name):
        if name == 'mileage':
            print('We noticed that the mileage attribute was read')
        return class_.__getattr__orig(self, name)#能否解释一下这个return的意义
    
    class_.__getattribute__ = new_getattr#这里也看不懂
    
    return class_#这里的class_到底算变量,还是类
@object_counter
class Car:
    def __init__(self, VIN):
        self.mileage = 0
        self.VIN = VIN

car = Car('ABC123')
print('The mileage is', car.mileage)
print('The VIN is', car.VIN)

def object_counter(class_):
    class_.__getattr__orig = class_.__getattribute__#这个动态给参数class_添加新的方法__getattr__orig,指向class_对象元素的__getattribute__获取属性的方法
 
    def new_getattr(self, name):
        if name == 'mileage':#这里做属性拦截,访问某个属性时,name变量存储要访问的属性名,如果访问属性名mileage,则打印下面的信息
            print('We noticed that the mileage attribute was read')
        if name=="xxx":#这属性没有定义,可以直接返回一个新值,不能调用下面的代码,会出错
            return "xxx"
        return class_.__getattr__orig(self, name)#这里调用原始的对象__getattribute__方法获取属性值后作为函数返回值
    
    class_.__getattribute__ = new_getattr#重新定义对象的__getattribute__指向新的方法new_getattr    
    
    print(type(class_))
    return class_#这里的class_为动态新增了__getattr__orig方法的Car类
@object_counter
class Car:
    def __init__(self, VIN):
        self.mileage = 0
        self.VIN = VIN

car = Car('ABC123')
print('The mileage is', car.mileage)
print('The VIN is', car.VIN)

print('The VIN is', car.xxx)#未定义的属性

 

1.class_object_counter函数的形参啊,它本身是个变量,也可能是个类,那要看你传进来个什么,你传进来个类它就是类
2.class_.__getattribute__ = new_getattr,这是把函数new_getattr本身当做变量存进了__getattribute__ 这个属性里面
那么你执行class_.__getattribute__()就等于执行new_getattr()
3.return class_.__getattr__orig(self, name)
这函数本身是从这来的:class_.__getattr__orig = class_.__getattribute____getattribute__又是从new_getattr来的,这就相当于一个递归
但是这个递归简直是《如何逼死运维》的教科书式写法

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632这篇文章讲的很详细,请看:python(decorator)