在编写class中,我们有时会期望部分属性只读,或者只写,或者其他。
只需要使用property就可以做到这一点。
下例中我们使用装饰器,包裹了四个同名函数,但使用中,它们则像一个变量一样。
其中我们控制了:
- name只允许被赋予 str 类型的值(@property.setter)
- name不允许被删除(@property.deleter)
- name允许被获取(@property.getter)
class Person:
def __init__(self, name):
self.__name = name
@property
def name(self):
'''绑定属性'''
return self.__name
@name.setter
def name(self, value):
'''写'''
if not isinstance(value, str):
raise TypeError('Expected a string')
self.__name = value
@name.deleter
def name(self):
'''删'''
raise AttributeError("Can't delete attribute")
@name.getter
def name(self):
'''读'''
return self.__name
这些函数除了被使用时当作一个属性,编写过程是完全和普通函数一样的,所以也可以控制一些魔幻的东西,譬如 name 被赋值时,我们可以改变其他属性的值(譬如 性别)。
补充:
无需写全三个方法(.setter
, .getter
, .deleter
),没有定义的方法,会执行默认操作。
-
评论说的对:上例的
.getter
可以不写,因为是默认操作方式。 -
另一种注册方法
class Person:
def __init__(self, name):
self.set_name(name)
def get_name(self):
return self.__name
def set_name(self, value):
if not isinstance(value, str):
raise TypeError('Expected a string')
self.__name = value
def del_name(self):
raise AttributeError("Can't delete attribute")
__name = property(get_name, set_name, del_name)
这在代码重构中十分有用,不需要改变原有的api,照样能更新内部的方法。
网友评论