描述器定義方式一:
class Person:
def __init__(self):
self.__age = 18
def get_age(self):
return self.__age
def set_age(self, value):
if 0 <= value <= 200:
self.__age = value
def del_age(self):
del self.__age
age = property(get_age, set_age, del_age)
p = Person()
print(p.age)
p.age = 20
print(p.age)
print(p.__dict__)
del p.age
print(p.__dict__)
#運行結(jié)果
18
20
{'_Person__age': 20}
{}
class Person:
def __init__(self):
self.__age = 18
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if isinstance(value, int) and 0 <= value <= 200:
self.__age = value
else:
print("value 的值設(shè)置錯誤弄诲,你輸如正確的數(shù)值 ")
@age.deleter
def age(self):
del self.__age
p = Person()
print(p.age)
p.age = 20
print(p.age)
print(p.__dict__)
del p.age
print(p.__dict__)
#運行結(jié)果
18
20
{'_Person__age': 20}
{}
描述器定義方式二:
# 如果實現(xiàn)了 __get__ ,__set__ ,判定為"資料描述器"
# 如果只實現(xiàn)了 _get__ , 判定為"非資料描述器"
# 描述器和實例屬性同名時, 操作的優(yōu)先級問題
# 資料描述器 > 實例字典 > 非資料描述器
# 描述器僅在新式類中生效
class Age:
def __get__(self, instance, owner):
return instance.v
def __set__(self, instance, value):
instance.v = value
def __delete__(self, instance):
del instance.v
class Person:
age = Age()
def __init__(self, age):
self.age = age
p = Person(20)
print(p.age)
print(p.__dict__)
del p.age
print(p.__dict__)
#運行結(jié)果
20
{'v': 20}
{}
PS1:
一個實例屬性的正常訪問順序
實例對象自身的dict字典
對應(yīng)類對象的dict字典
如果有父類, 會再往上層的dict字典中檢測
如果沒找到, 又定義了getattr方法, 就會調(diào)用這個方法
PS2:
而在上述的整個過程當中, 是如何將描述器的get方法給嵌入到查找機制當中?
就是通過這個方法進行實現(xiàn) __getattribute__
內(nèi)部實現(xiàn)模擬:
如果實現(xiàn)了描述器方法get就會直接調(diào)用
如果沒有, 則按照上面的機制去查找
裝飾器:
def check(func):
def inner():
print("check")
func()
return inner
@check
def fss():
print("發(fā)說說")
# fss = check(fss)
fss()
使用類當做裝飾器來使用
class check:
def __init__(self, func):
self.f = func
def __call__(self, *args, **kwargs):
print("check")
self.f()
def fss():
print("發(fā)說說")
fss = check(fss)
fss()