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)

看不懂没关系,欢迎评论区讨论呦~~

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