有时候,我们需要对数据属性给出更精确的控制。按照其他语言的的实现方法,可以编写 “getter”、“setter” 或 “deleter” 一类的方法。如下示例:
class Student:
def __init__(self, name):
self.name = name
self.__is_male = None # 为了演示目的,特别通过私有的布尔类型变量存储性别
def get_gender(self):
return '男' if self.__is_male else '女'
def set_gender(self, gender):
match gender.lower():
case '男' | '男性' | 'male' | 'm' | 'man':
self.__is_male = True
case '女' | '女性' | 'female' | 'f' | 'woman' | 'w':
self.__is_male = False
case _:
self.__is_male = None
def del_gender(self):
del self.__is_male
xiaoming = Student('小明')
xiaoming.set_gender('男')
print(xiaoming.get_gender())
xiaoming.del_gender
Python 有一个内置的 property 函数,用于创建一个特征属性 property 对象。其签名为:
class property(fget=None, fset=None, fdel=None, doc=None)
property 对象有三个方法:getter()、setter() 和 delete(),可以分别通过 fget、fset 和 fdel 参数指定。这里 fget 是获取属性值的函数,fset 是用于设置属性值的函数,fdel 是用于删除属性值的函数,doc 用于为属性对象创建文档字符串。
可以通过为所定义的类创建一个 property 类型的类变量来定义一个托管属性,见下页示例。
使用 property() 函数:
class Student:
def __init__(self, name):
self.name = name
self.__is_male = None # 为了演示目的,特别通过私有的布尔类型变量存储性别
def get_gender(self):
return '男' if self.__is_male else '女'
def set_gender(self, gender):
match gender.lower():
case '男' | '男性' | 'male' | 'm' | 'man':
self.__is_male = True
case '女' | '女性' | 'female' | 'f' | 'woman' | 'w':
self.__is_male = False
case _:
self.__is_male = None
def del_gender(self):
del self.__is_male
# gender 是一个托管的属性
gender = property(get_gender, set_gender, del_gender, "I'm the 'gender' property.")
xiaoming = Student('小明')
xiaoming.gender = '男'
print(xiaoming.gender) # 男
del xiaoming.gender
这里 xiaoming.gender 将调用其“getter”,xiaoming.gender = value 将调用其“setter”,del xiaoming.gender 将调用 “deleter”。
以上代码可进一步用 Python 的装饰器来实现,见下页代码。
装饰器为一种语法糖,它是返回值为另一个函数的函数。通常使用 @wrapper 形式的语法来进行函数变换,从而修改其他函数功能,使代码更简洁。
下页 @property 装饰器会创建一个与 gender() 方法同名的特征属性 gender,将该方法指定给其 “getter”,将 gender 的文档字符串设置为 "I'm the 'gender' property.",然后将同名的 gender() 方法分别指定给 gender 特征属性的 “setter” 和 “deleter” 方法。
使用 @property 装饰器:
class Student:
def __init__(self, name):
self.name = name
self.__is_male = None
@property
def gender(self):
"""I'm the 'gender' property."""
return '男' if self.__is_male else '女'
@gender.setter
def gender(self, gender):
match gender.lower():
case '男' | '男性' | 'male' | 'm' | 'man':
self.__is_male = True
case '女' | '女性' | 'female' | 'f' | 'woman' | 'w':
self.__is_male = False
case _:
self.__is_male = None
@gender.deleter
def gender(self):
del self.__is_male
xiaoming = Student('小明')
xiaoming.gender = '男'
print(xiaoming.gender) # 男
del xiaoming.gender