![01fe385600ec1c3bbafb35f30d8d9e1c.png](https://i-blog.csdnimg.cn/blog_migrate/ca4213cb5a2092d2b73198da159b4692.jpeg)
在Python开发时,考虑到安全性,我们会通过使用 '__' 定义私有属性,以限制类外或者子类都不能直接进行访问、操作。但同时,这些私有属性并不是一成不变的,所以我们还需要提供私有属性的对外操作方式。通常,我们使用Python Property 动态属性来实现。
Python Property 的应用场景:
- 限制属性的特征,比如成绩不能是负分。
- 属性动态变化,比如年龄属性随着时间而变化。
- 限制属性的只读属性。
![d34397a093e02245ddcc97c75e5997d4.png](https://i-blog.csdnimg.cn/blog_migrate/b4cfac1270059bbced9ca6fd72cd3a2e.jpeg)
如上,我们创建了一个 Student 类,我希望通过实例来获取每个学生姓名,成绩信息。其中我们将学生成绩信息设置为类的私有属性(__score),我们可以通过如下自定义方法,调用自定义方法对私有属性进行操作。
![0fb447ddf74efc767145db868af2d3a9.png](https://i-blog.csdnimg.cn/blog_migrate/583ea2a43ff121b60864d6f3af6b9ebc.jpeg)
我们可以通过调用get_score、set_score方法实现对学生成绩的读写,如下:
![dd15d4ad2d3b28af1a0e3b7d1cd0156d.png](https://i-blog.csdnimg.cn/blog_migrate/957285e26386019dc5f6462050d8bae6.jpeg)
我们通过自定义方法实现了对外提供私有属性的访问方式,但我们发现,在使用的过程中需要频繁的调用自定义方法,如 Tony.set_score(999),使得代码并不够简洁。
接下来我们就来介绍一下 property。首先,我们可以通过调用 property方法对 get_score, set_score 方法进行封装,然后操作私有属性。
property 语法
![16cba9f3d7738c3cb10f3c1747f7a2e6.png](https://i-blog.csdnimg.cn/blog_migrate/cd71971212fcacd29ed3bf52ccdb9ec9.jpeg)
参数
- fget : 获取属性值的函数名。
- fset : 设置属性值的函数名。
- fdel : 删除属性值函数名。
- doc : 属性描述信息。
![f17e12ec06f89466784b0f6a68cd2d90.png](https://i-blog.csdnimg.cn/blog_migrate/0dd8e1ad0fefe6f541a25874771f4922.jpeg)
上面使用 property 方法对 get_score, set_score方法进行封装,同样实现了访问私有属性的目的,但是这种方式还是比较麻烦的。
接下来,我们在尝试 直接使用 property 修饰同名函数的形式,来实现对私有属性的访问操作,这也是实际开发应用中最常简的一种方式,如下:
![12e43ac1dc4c4ef64bf49ea68e83ae04.png](https://i-blog.csdnimg.cn/blog_migrate/9013970226eaafb11ebb7e471ee0952b.jpeg)
如下,当访问、更新、删除私有属性时,该如何使用 property 进行修饰。
![1313e9de3620b37894f698ac2c89bcfc.png](https://i-blog.csdnimg.cn/blog_migrate/95610653ceaa3e68d4339c40c5fb6266.jpeg)
通过上面代码执行结果,我们可以发现:
- 获取私有属性时,自动触发执行被@property修饰的score方法,默认执行getter的方法。
- 设置私有属性时,自动触发执行被@score.setter修饰的score方法。
- 删除私有属性时,自动触发执行被@score.deleter修饰的score方法。
需要注意的是在 Python 经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法。在 新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法。
假如此时,我们发现Tony的成绩是999,原来是不小心多输入的了一个9,我们需要在对私有属性赋值时进行限制,如下:
![713f5462576a595d0feec42caac2104d.png](https://i-blog.csdnimg.cn/blog_migrate/7fdf0e16ca5b3cfa24c0010f6b8c1c40.jpeg)
我们在被@score.setter修饰的score方法中增加了成绩的范围判断,此时当我们执行 Tony.score = 999 时,因 999 不符合 限制条件,则会抛出 ValueError: score invalid异常。
假如现在要求不允许成绩信息被录入后进行任何修改,我们需要把私有属性设置为只读,方法很简单,把 setter 部分注释掉就可以了,如下。
![3c7b2a0b2a10097b0446e69e101e77b0.png](https://i-blog.csdnimg.cn/blog_migrate/b8a219067362071554eeb6097891d5db.jpeg)