zoukankan      html  css  js  c++  java
  • 面向对象高级之 __getattr__,__setattr__,__delattr__

    __getattr__

    拦截对象的点号运算。
    当对为定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法。如果继承树可以找到该属性,则不调用此方法

    class empty:
        def __getattr__(self,attrname):
            if attrname == 'age':
                return 40
            else:
                return AttributeError,attrname
    
    # `__getattr__`只有在使用点调用属性且属性不存在的时候才会触发
    x = empyte()
    print(x.age) #40
    print(x.name)  #报错
    

    __serattr__

    拦截所有属性的赋值语句。
    如果定义了这个方法,self.attr = value 就会变为 self.__setattr__('attr',value)
    当在__setattr__方法内对属性进行赋值时,不可使用self.attr = value,因为他会再次
    调用 self.__setattr__('attr',value),则会形成无限递归,导致堆栈溢出异常。应该通过对属性字典做索引运算来赋值任何实例属性,也就是使用self.__dict__['name']=value

    class PrivateExc(Exception):
        pass
    class Privacy:
        def __setattr__(self,attrname,value):
            if attrname in self.privates:
                raise PrivateExc(attrname,self)
            else:
                self.__dict__[attrname] = value
    
    class Test1(privacy):
        privates = ['age',]
    
    class Test2(privacy):
        pricates = ['name','age']
        def __init__(self):
            self.__dict__['name']='sun'
    

    __delattr__

    删除属性的时候触发
    注意无限递归的问题,不要在__delattr__内部直接使用del删除属性

    def __delattr__(self,item):
        #del self.item 这样就无限递归了
        self.__dict__.pop(item) #正确的方式
    
  • 相关阅读:
    JVM启动参数小结
    Java 线程池学习
    myeclipse 8.5安装freemarker插件方法
    开源文件比较工具:WinMerge、KDiff3、diffuse
    初探淘宝技术构架
    Java获取IP地址:request.getRemoteAddr()注意
    Spring MVC 教程,快速入门,深入分析
    分布式服务框架 Zookeeper -- 管理分布式环境中的数据
    YARN作业提交流程剖析
    经典的MapReduce1解析
  • 原文地址:https://www.cnblogs.com/guodengjian/p/9200685.html
Copyright © 2011-2022 走看看