特性概述
特性是指的property
.
property
这个词的翻译一直都有问题, 很多人把它翻译为属性, 其实是不恰当和不准确的. 在这里翻译成特性是为了和属性区别开来.
属性是指的attribute
, 我们以前学习的实例变量和类变量是attribute
, 所以也可以叫做实例属性和类属性.
property
(特性)到底是个什么东西?
我们前面学习类属性和实例属性的时候知道, 访问他们的时候就可以直接获取到这些属性的值.
而特性可以看成一种特殊的属性, 为什么呢?
但从访问方式来看, 特性和属性看不出来差别, 但是特性实际上会经过计算之后再返回值. 所以每一个特性都始终与一个方法相关联.
定义特性
定义特性和定义实例方法类似, 只需要另外在方法上面添加一个内置装饰器:@property
访问特性和访问实例变量完全一样, 不需要使用添加括号去调用.
import math
class Circle:
def __init__(self, r):
self.r = r
@property
def area(self):
"""
定义特性
这个特性是计算出来圆的面积
:return:
"""
return math.pi * (self.r ** 2)
c = Circle(10)
print(c.area)
很明显, 特性背后的本质是一个方法的存在, 所以你不可能在外面去修改这个特性的值!
视图修改特性的值只会抛出一个异常.
c.area = 100
使用特性的设计哲学
这种特性使用方式遵循所谓的 统一访问原则.
实际上, 定义一个类总是保持接口的统一总是好的.
有了特性, 把访问属性和访问方法统一了, 都像在访问属性一样, 省得去考虑到底什么时候需要添加括号,什么时候不用添加括号.
特性的拦截操作
python 还提供了设置和删除属性.
通过给方法添加其他内置装饰器来实现
设置:@特性名.setter
删除:@特性名.deleter
class Student:
def __init__(self, name):
self._name = name # name 是特性了, 所以用实例变量存储特性的值的需要换个变量名!!!
@property
def name(self):
return self._name
@name.setter
def name(self, name):
if type(name) is str and len(name) > 2:
self._name = name
else:
print("你提供的值" + str(name) + "不合法!")
@name.deleter
def name(self):
print("对不起, name 不允许删除")
s = Student("李四")
print(s.name)
s.name = "xyxyxy"
print(s.name)
s.name = "张三"
print(s.name)
del s.name