python 數據描述符的使用(附帶裝飾器)


什麼是python描述符: 類裏面有 __get____set____del__ 的就叫描述符


屬性查找優先級

  1. 類屬性
  2. 數據描述符 (同時實現__get____set__)
  3. 實例屬性
  4. 非數據描述符 (只實現__get__)
  5. __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)

看不懂沒關係,歡迎評論區討論呦~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章