一、属性装饰器的基本用法说属性装饰器之前,我们先来看一个例子:classMyClass:def__init__(self,word):self。_word=worddefword(self):returnself._wordmy=MyClass('Hello')print(my.word())print(my.word)执行这段代码,会输出如下结果:Hello>这段代码的主要作用是通过word方法返回一个字符串。而最后一行直接访问了word方法。在Python语言中,一切都可以看作是一个对象,方法也不例外。所以直接输出word方法的对象形式。但是my.word的调用形式其实是一种访问属性的方式,所以这段代码也可以看做是将word方法作为属性,而不是获取word对象本身。因此,如果要将方法这个词作为属性来使用,就必须使用属性装饰器。我们来看看改进后的代码:classMyClass:def__init__(self,word):self._word=word#将word方法转为属性@propertydefword(self):returnsself._wordmy=MyClass('Hello')#OutputHelloprint(my.word)这段代码使用了@property修饰word的方法。这时候word方法会直接变成一个属性,这样就可以使用my.word的形式来调用word方法了。当你运行这段代码时,会输出Hello。我们可以看到,只需1行代码就可以将任何普通的Python方法变成一个属性。如果方法被@property修饰,就不能再作为方法调用。比如word方法不能再以my.word()的形式调用,否则会抛出如下异常:2.属性装饰器的原理可能有很多小伙伴很奇怪,为什么可以Python方法直接用@property修饰方法变成属性?本节将详细介绍属性装饰器的原理。首先,我们必须了解什么是财产。使用如下代码输出属性:print(property)输出如下:很明显,property是一个类。Python装饰器其实是一个语法糖,本质上是把Python装饰器当作函数使用,将装饰器装饰的方法/函数作为参数值传递给装饰器函数。比如用@property修饰word方法,就相当于用下面的代码来包装word方法:property(word)也就是说word方法被@property修饰后,会成为属性类。下面的代码可以用来演示属性装饰器的原理。这段代码中word方法是用@property修饰的,new_word方法是直接通过创建property实例来修饰的。classMyClass:def__init__(self,word):self._word=word@propertydefword(self):returnsself._word#输出修饰词的类型方法print('word:',type(word))defnew_word(self):returnsself._word#输出未修改的new_word方法的类型print('new_word:',type(new_word))new_word=property(new_word)print(type(new_word))my=MyClass("android")print(my.word)print(my.new_word)执行这段代码,会输出如下内容:从输出结果可以看出@property修饰的word方法的类型是属性类,而new_word方法的类型不是@property修饰的是函数类。而且通过创建属性实例包装的new_word方法也可以作为属性使用,相当于下面的代码:@propertydefnew_word(self):returnsself._word3。用@property修饰使属性可写可删除的方法是只读属性,既不能写入也不能删除,否则会抛出异常。如果使用my.word='new'设置word属性,会抛出如下异常。如果使用delmy.word删除word属性,会抛出如下异常:其实属性类也有setter方法和deleter方法,可以使属性可写可删除。首先看下面的代码:#设置deletable属性,当word属性被删除时会调用这个方法@word.deleterdefword(self):print('deleteword')self._word=''#创建一个属性实例,将new_word方法变成一个可读写可删除defnew_word(self):returnsself._word#把new_word改成只读属性,需要把property实例赋值给一个新的变量,否则后面会被new_word方法覆盖new_word1=property(new_word)defnew_word(self,value):self._word=value#将new_word设置为可写属性new_word1=new_word1.setter(new_word)defnew_word(self):print('deletenewword')#将new_word设置为可删除属性new_word=new_word1.deleter(new_word)my=MyClass('hello')打印(my.word)my.word='world'#defword(self,value):print(my.word)delmy.wordprint(my.word)print('--------')my=MyClass('ios')print(my.new_word)my.new_word='harmony'print(my.new_word)delmy.new_wordprint(my.new_word)执行这段代码,输出结果如下:4.获取原始方法@property修饰的方法将被属性实例替换。那么如何获取原始方法呢?这是通过property类的以下三个方法:(1)fget:获取@property或@property.getter修饰的方法(2)fset:获取@property.setter修饰的方法(3)fdel:获取@property.deleter修饰的方法下面的例子中分别获取了word属性的三个原始方法,这三个原始方法分别调用classMyClass:def__init__(self,word):self._word=word@propertydefword(self):返回自我。=word.fdelmy=MyClass('android')print(my.fget_word())my.fset_word('harmony')print(my.fget_word())print(my.fdel_word())执行这段代码会输出如下结果。