它使用额外的Python语句修改旧对象并返回相同的引用。例如,考虑下面的类,它有两个方法:__init__和display。__init__方法在显示输出name时初始化name变量:classStudent:def__init__(self,name):self.name=namedefdisplay(self):print('Name:',self.name)被装饰在Python这个类,我们可以给这个类增加新的方法或者修改现有的方法,或者两者兼而有之。此外,在Python中有两种方法可以做到这一点,要么使用函数装饰器,要么使用类装饰器。让我们一个一个地看例子。用函数装饰器装饰类要用函数装饰器装饰类,接受类作为参数,修改其代码并在最后返回类。defmydecorator(student):#定义一个新的显示方法defnewdisplay(self):print('Name:',self.name)print('Subject:Programming')#replacethedisplaywithnewdisplaystudent.display=newdisplay#return修改后的学生返回student@mydecoratorclassStudent:def__init__(self,name):self.name=namedefdisplay(self):print('Name:',self.name)obj=Student('PencilProgrammer')obj.display()'''Name:PencilProgrammerSubject:Programming'''如果类中不存在display方法,则会在类中添加newdisplay作为显示方法。由于类引用在装饰器函数中可用,因此除了修改现有方法外,我们还可以向类中添加新的属性和方法。用类装饰器装饰类要用类装饰器装饰类,接受类引用作为参数(在装饰器的__init__方法中),在__call__方法中修改其代码,最后返回修改后的类的实例。classMydecorator:#accept类作为参数def__init__(self,student):self.student=student#接受类的__init__方法参数def__call__(self,name):#定义一个新的显示方法defnewdisplay(self):print('Name:',self.name)print('Subject:Python')#用新显示替换显示self.student.display=newdisplay#return类的实例obj=self.student(name)returnobj@MydecoratorclassStudent:def__init__(self,name):self.name=namedefdisplay(self):print('Name:',self.name)obj=Student('PencilProgrammer')obj.display()'''Name:PencilProgrammerSubject:Python'''这里唯一的区别是我们返回一个对象引用类参考。原文:https://pencilprogrammer.com/decorate-python-class/
