什麼是python描述符: 類裏面有 __get__
或__set__
或__del__
的就叫描述符
屬性查找優先級
- 類屬性
- 數據描述符 (同時實現
__get__
和__set__
) - 實例屬性
- 非數據描述符 (只實現
__get__
) __getattr__
通過代理和描述符實現屬性懶加載
這裏是使用裝飾器的方式實現的懶加載。可以將耗時的操作放到方法裏面。在未使用的時候是一個方法,當第一次使用過後就會替換掉方法,併爲之設置屬性值。
注意,只有在使用的時候纔會執行函數裏面的代碼,並且只執行一次,再次使用的時候直接返回值
關鍵代碼:
value = self.method(instance)
setattr(instance, self.method_name, value)
...
@LazyLoad
def resource(self):
代碼如下:
from functools import update_wrapper
class LazyLoad(object):
def __init__(self, method):
self.method = method
self.method_name = method.__name__
update_wrapper(self, self.method)
def __get__(self, instance, owner):
print "-+" * 20
print "__get__"
print self, instance, owner
value = self.method(instance)
setattr(instance, self.method_name, value)
print "-+" * 20
return value
class T2(object):
def __init__(self):
self._t = 1
@LazyLoad
def resource(self):
print "execute it in resource !"
z = [str(i) for i in range(0, 10)]
return ",".join(z)
t2 = T2()
print type(t2.resource)
print t2.resource
print t2.resource
使用裝飾器和非數據描述自定義實現 staticmethod
class StaticObj(object):
"""這裏是自定義的非數據描述符"""
def __init__(self, method):
self.method = method
def __get__(self, instance, owner):
return self.method
def static_m(func):
return StaticObj(func)
class T3(object):
def __init__(self):
print "create it "
@static_m
def test(a, b):
print 1, a, b
print T3.test(2,3)
# 輸出 1 2 3
可以像下面一樣理解
test
經過裝飾器後,就是StaticObj(test)
- 然後點操作會執行
__get__
返回 test 函數,此函數是不需要綁定的 - 後面的
(2,3)
會執行 test(2,3)
看不懂沒關係,歡迎評論區討論呦~~