class property([fget[, fset[, fdel[, doc]]]])
# fget是用于获取属性值的函数
# fset是用于设置属性值的函数
# fdel是用于删除属性值的函数
# doc是文档字符串
下面是官方文档上的一个例子:
In [2]: class C:
def __init__(self):
print("invoke __init__")
self._x = None
def getx(self):
print("invoke getx")
return self._x
def setx(self, value):
print("invoke setx")
self._x = value
def delx(self):
print("invoke delx")
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
当访问c.x时会调用getx方法,当为c.x设置值时会调用setx方法,删除c.x时会调用delx方法。
在对实例属性的获取和设定上,我们希望增加一些额外的处理过程(比如类型检查或者验证)。要自定义对属性的访问,一种简单的方式是将其定义为property。比如下面的代码定义了一个property,增加了对属性的类型检查。
In [9]: class Person:
def __init__(self, first_name):
self.first_name = first_name
print("invoke __init__")
@property
def first_name(self):
print("invoke get first_name")
return self._first_name
@first_name.setter
def first_name(self, value):
print("invoke set first_name")
if not isinstance(value, str):
raise TypeError("Expected a string")
self._first_name = value
@first_name.deleter
def first_name(self):
raise AttributeError("Can't delete attribute")
你可能会问为什么在init方法中设定的是self.first_name而 不是self._first_name?在这个例子中,property的全部意义就在于我们设置属性时可以执行类型检查。因此,你也想让这种类型检查在初始化的时候也可以进行。所以,在init中设置self.first_name,实际上会调用到setter方法(因此就会跳过self.first_name而去访问self._first_name)。 property使用场景: 只有当确定需要在访问属性必完成一些额外的处理任务时,才应该使用property.
Ref: 1.官方文档 2.python cookbook