python利用类装饰器给类定义打补丁

我们希望检查或者改写一部分类的定义,以此来修改类的行为,但是不想通过继承或者元类的方式来做。

    如果希望解决这个问题,那么类装饰器绝对是首选。

    下面这个示例演示了如何使用类装饰器来重写__getattribute__特殊方法,并为它增加了日志功能:

from functools import wraps
 
def log_getattribute(cls):
    #获取原始的实现方法
    orig_getattribute = cls.__getattribute__
 
    #定义新的实现方法,记得要返回原始的实现方法
    def new_getattribute(self,name):
        print("getting:",name)
        return orig_getattribute(self,name)
 
    #修改方法映射并返回
    cls.__getattribute__ = new_getattribute
    return cls
 
@log_getattribute
class A:
    def __init__(self,x):
        self.x = x

    如果尝试使用该方法来访问类实例的属性,会得到以下结果:

>>> a=A(12)
>>> a.x
getting: x
12
>>> a.spam()
getting: spam

    类装饰器往往是作为混合类或元类等高级技术的替代方案,对于本文中的问题,我们还有一种方法是使用继承来解决:

class LoggedGetattribute:
    def __getattribute__(self, name):
        print("getting:",name)
        return super().__getattribute__(name)
 
class A(LoggedGetattribute):
    def __init__(self,x):
        self.x = x
    def spam(self):
        pass

    这么做也是可行的,这样在父类中使用super()需要涉及到方法解析顺序(MRO)、super()以及其他和继承相关的知识。

    从某些角度上来看,使用类装饰器显得更加直观一些,而且不会在继承体系中引入新的依赖关系。而且事实证明,因为不使用super()函数,所以运行速度也会更加快。
python利用类装饰器给类定义打补丁_第1张图片

微信公众号:进击的代码Amos

每天更新Java、python学习资料、技术干货。分享见解,共同成长。

关注公众号,免费获取众多电子版经典教材。

python利用类装饰器给类定义打补丁_第2张图片

你可能感兴趣的:(Python)