#property简介
#1.用于赋值,修改,删除, 当然如果觉得property麻烦完全可以不用
#2.property(特性) 是类属性, 因此可以被继承
#Person中定义了4个简单的函数
class Person:
def __init__(self,name):
self._name = name
def getName(self):
print('getName')
return self._name
def setName(self,value):
print('setName')
self._name = value
def delName(self):
print('delName')
del self._name
#name是一个类属性,property返回一个特性对象,Person.name对其引用
#4个参数,分别是获取,修改/设置 , 删除,以及文档字符串
name = property(getName,setName,delName,'property Docs')
p = Person('hi')
#p.name 相当于调用p.getName , p.name = 'xx' <==> p.setName('xx')
print(p.__dict__) #{'_name': 'hi'} 可以看到name属性 属于 类对象Person,不属于实例
#接下使用装饰器来使用property
#装饰器的调用情况
# @tracer
# def func() => func = tracer(func) ,func被重新赋值了
# property函数正好能满足这一点
class PropertyTest:
def __init__(self,value = 'PropertyTest'):
self._name = value
@property
def name(self): #name = property(name,None,None,None) , 至此name是一个特性对象
'name property docs'
print('getname')
return self._name
@name.setter #name = name.setter(name)
def name(self,value):
print("setter")
self._name = value
@name.deleter #name = name.deleter(name)
def name(self):
print('remove..')
del self._name
p = PropertyTest()
p.name = '123'
**重点: 使用@property时, 在class内出现多个同名的函数(def name) , 为什么一定这样使用?
上面的例子中 Class 内部只有1个name的特性对象
property() 返回一个特性对象, property.setter / getter / deleter 这些函数,将返回property自身的一个副本,
相当于,class 内的多个同名 (def name) 函数实际上只是一个property特性对象
接下来看一下,如果不使用同名的属性名, 该怎么用:
#Property 函数的 getter / setter / deleter 都会返回自身的副本
class Person:
def __init__(self,value = 'fu'):
self._name = value
@property
def name(self): #现在name是一个特性对象
'property doc'
print("fetch ...")
return self._name
@name.setter #用一个特性对象的setter 创建了一个新的特性对象,同时拥有设置的函数
def setName(self,value):
print('setName')
self._name = value
@name.deleter #这个与第一个特性对象是同一个
def name(self):
del self._name
#由于property的setter 会返回一个自身的副本,所以,setName 是一个新的特性对象.
#name = 'xx' 这样的赋值操作将出错, 要使用, p.setName = 'xxx'
p = Person()
print(Person.name)
print(Person.setName) #可以看到这2个是不一样的特性对象.Class内已经出现的2个特性对象
p.setName = '123' #所以当赋值时,只能这样用, p.name 并没有setter的函数