Python @property修饰器
基本用法
必须使用@property,才可以使用@setter、@getter、@delete,否则报错
@property(只读)
@setter(设置)
@getter(读取) (@property已经有读取的功能,不需要使用,使用则会调用@getter读取而不是@property下的方法)
@delete(删除)
class classA():
def __init__(self):
self._name = 0
@property
def name(self):
print('property')
return self._name
@name.setter
def name(self, name):
print('name.setter')
self._name = name
@name.getter
def name(self):
print('name.getter')
return self._name
@name.deleter
def name(self):
print('name.deleter')
del self._name
a = classA()
a.name = 1
print(a.name)
del a.name
output:
name.setter
name.getter
1
name.deleter
注:使用函数名自动调用函数。使用注释名@name.setter,我们执行a.name = 1,相当于调用@name.setter下的函数,并将等号后的值当为参数。
可以像其他语言一样我们可以添加一个简单判断,来防止name属性出现不合适的值
@name.setter
def name(self, name):
print('name.setter')
if not isinstance(name,str):
raise ValueError('名字应该为字符')
return
self._name = name
注:1.上述代码中 isinstance()是python官方文档推荐的判断属性属于哪一个类的函数。
2. raise ValueError() 抛出一个错误。
名称解释
- 有同学会问 代码1-1 中classA的属性是_name,为什么我操作的确是name,其name本质是一堆函数,需要一个外部变量来存储值,真_正的操作的对象其实是_name;
- 相信同学们注意到了如果classA有个成员属性正好叫name那怎么办,不要怀疑程序会报错;
@property
def name(self):
pass
@name.setter
@name.getter
@name.deleter
又有同学注意到了,代码1-3 中类如setter前面的name到底有什么作用,如果单纯用函数写不也一样可以实现功能吗?
python中的函数重载和别的语言中的不一样,遇到同名函数直接就新加载的替换老的同名函数,如果手动写的话,可就不可以使用,同名函数和使用函数名自动调用函数了。所以类如setter前面的name是为了区分函数,避免被覆盖。