Python基础|类(四)
接上回说:概要
安装环境
变量
布尔、数字、字符串
列表
文件与异常(一)
文件与异常(二)
文件与异常(三)
类(一)
类(二)
类(三)
★ 使用属性对特性进行访问和设置
property 属性
attribute 特性
有一些面向对象的语言支持私有特性。这些特性无法从对象外部直接访问,我们需要编写 getter 和 setter 方法对这些私有特征进行读写操作。
Python 不需要 getter 和 setter 方法,因为 Python 里所有特性都是公开的,使用时全凭自觉。如果你不放心直接访问对象的特性,可以为对象编写 setter 和 getter 方法。 但更具Python 风格的解决方案是使用属性(property)。
下面例子中,首先定义一个 Duck 类,他仅包含一个 hidden_name 特性。我们不希望别人能够直接访问这个特性,因此需要定义两个方法:getter 方法(get_name())和 setter方法(set_name())。我们在每个方法中都添加一个 print() 函数,这样就能方便地知道它们何时被调用。最后,把这些方法设置为 name 属性:
http://www.yeslab.net/Uploads/201801/5a706f96a0d21.jpg
这两个新方法在最后一行之前都与普通的 getter 和 setter 方法没有任何区别,最后一行则把这两个方法定义为了 name 属性。 property() 的第一个参数是 getter 方法,第二个参数是 setter 方法。现在,当你尝试访问 Duck 类对象的 name 特性时,get_name()会被自动调用:
http://www.yeslab.net/Uploads/201801/5a706fcd3d457.jpg
当然,也可以显式调用 get_name() 方法,它就像普通的 getter 方法一样:
http://www.yeslab.net/Uploads/201801/5a70702571949.jpg
当对 name 特性执行赋值操作时,set_name() 方法会被调用:
http://www.yeslab.net/Uploads/201801/5a70703fee193.jpg
也可以显式调用 set_name() 方法:
http://www.yeslab.net/Uploads/201801/5a70705bb990a.jpg
另一种定义属性的方式是使用装饰器(decorator)。下一个例子会定义两个不同的方法,它们都叫 name(),但包含不同的装饰器:
@property, 用于指示 getter 方法
@name.setter, 用于指示 setter 方法
http://www.yeslab.net/Uploads/201801/5a70708c95da9.jpg
你仍然可以像之前访问特性一样访问 name, 但这里没有显式的 get_name() 和 set_name() 方法:
http://www.yeslab.net/Uploads/201801/5a7070b46362f.jpg
实际上,如果有人能猜到我们在类的内部用的特性名是 hidden_name,他仍然可以直接通过 fowl.hidden_name 进行读写操作。
在前面几个例子中,我们都使用 name 属性指向类中存储的某一特性(在我们的例子中是 hidden_name)。除此之外,属性还可以指向一个计算结果值。我们来定义一个 Circle (圆)类,它包含 radius(半径) 特性以及一个计算属性 diameter(直径):
http://www.yeslab.net/Uploads/201801/5a7070cfc74ce.jpg
创建一个 Circle 对象,并给 radius 赋予一个初值:
http://www.yeslab.net/Uploads/201801/5a7070ec3de09.jpg
可以像访问特性(例如 radius)一样访问属性 diameter:
http://www.yeslab.net/Uploads/201801/5a7071021a09e.jpg
真正有趣的还在后面。我们可以随时改变 radius 特性的值,计算属性 diameter 会自动根据新的值更新自己:
http://www.yeslab.net/Uploads/201801/5a70711ad7b77.jpg
如果你没有指定某一特性的 setter 属性(@diameter.setter),那么将无法从类的外部对它的值进行设置。这对于那些只读的特性非常有用:
http://www.yeslab.net/Uploads/201801/5a707138408dd.jpg
与直接访问特性相比,使用 property 还有一个巨大的优势,如果你改变了某个特性的定义,只需要在类定义里修改相关代码即可,不需要再每一处调用修改。
http://www.yeslab.net/Uploads/201801/5a70714fc696d.jpg
动动手下周见
网址:www.yeslab.nethttp://www.yeslab.net/Uploads/201801/5a5ca7c2860b6.gif
感谢楼主分享! 好东西谢谢楼主分享
页:
[1]