python 数据描述符的使用(附带装饰器)

系统 1345 0

什么是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)

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


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论