zoukankan      html  css  js  c++  java
  • python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性

    先介绍几个类中的应用__getattr__,__setattr__,__get__,__set__,__getattribute__,。
    __getattr__:当在类中找不到attribute的时候,会调用__getattr__,并执行其中的自定义代码。所有在类中定义的属性都包含在__dict__中,也就是说如果在__dict__中找不到对应的属性名,则__getattr__被触发。
    class get_try(object):
        def __init__(self,value):
            self.value=value
        def __getattr__(self, item): #当找不到类中的属性的时候,将会被调用
            self.value=item

    if __name__ == "__main__":
        g=get_try('value')
        g.value1   #调用了g.value1,value1传入__getattr__的item.调用__getattr后,value=value1
        print g.value
    print g.__dict_
     
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter7.py
    value1
    {'value': 'value1'}
    结果打印的时候g.value的值是value1
     
    __getattribute__:无条件被调用,如果同时定义了__getattr__, 则__getattr__不会被调用。
    class get_try(object):
        def __init__(self,value):
            self.value=value
        def __getattr__(self, item):
            self.value=item
        def __getattribute__(self, item):
            print item

    if __name__ == "__main__":
        g=get_try('value')
        g.value1
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter7.py
    value1
    结果和之前一样。
     
    __setattr__当需要自己对属性进行定义的时候,会被调用。比如self.att=value就会变成self.__setattr__(“att”,value)class get_try():    def __init__(self,value):
            self.value=value
        def __getattr__(self, item):
            self.value=item
        def __getattribute__(self, item):
            print item
        def __setattr__(self, key, value):
            self.__dict__[key]=value


    if __name__ == "__main__":
        g=get_try('value')
        g.value1=3
        print g.value1
        print g.__dict__
    E:python2.7.11python.exe E:/py_prj/python_cookbook/chapter8.py
    3
    {'value1': 3, 'value': 'value'}
    需要注意的是在__setattr__的时候不能进行self.key=value的赋值,因为这个方式会使得不停调用self.__setattr__。这样会形成无穷的递归循环。最终导致堆栈溢出异常。当我们调用的时候,报的错误就像下面这种
      File "E:/py_prj/python_cookbook/chapter8.py", line 107, in __setattr__
        self.key=value
      File "E:/py_prj/python_cookbook/chapter8.py", line 107, in __setattr__
        self.key=value
    RuntimeError: maximum recursion depth exceeded
    其实我们不实现__setattr__的时候,在给属性赋值的时候也会隐含的调用这个函数。那么这样实现的好处是什么呢?好处是我们可以指定给哪些属性进行赋值。
    class get_try():
        def __init__(self,value):
            self.value=value
        def __getattr__(self, item):
            self.value=item
        def __getattribute__(self, item):
            print item
        def __setattr__(self, key, value):
            if key == 'value1':
                print 'incorrect key'
            else
    :
                self.__dict__[key]=value


    if __name__ == "__main__":
        g=get_try('value')
        g.value1=3
        g.value2=4
        print g.__dict__
    E:python2.7.11python.exe E:/py_prj/python_cookbook/chapter8.py
    incorrect key
    {'value2': 4, 'value': 'value'}
    上面的代码中,当对value1进行赋值的时候,首先进行判断。如果是value1则打印incorrect key。所以看到当对value2进行赋值的时候是成功的。同样的道理,我们可以用__setattr__在防止后续对类中已有的属性进行赋值:
    class get_try():
        def __init__(self,value):
            self.value=value
        def __getattr__(self, item):
            self.value=item
        def __getattribute__(self, item):
            print item
        def __setattr__(self, key, value):
            if key in self.__dict__:
                print 'already exist'
            else
    :
                self.__dict__[key]=value

    if __name__ == "__main__":
        g=get_try('value')
        g.value=4
        g.value1=3
        print g.__dict__
    E:python2.7.11python.exe E:/py_prj/python_cookbook/chapter8.py
    already exist
    {'value1': 3, 'value': 'value'}
    上面的代码中,首先判断赋值的对象是否已存在,如果存在则打印already exist
     
  • 相关阅读:
    asp.net调用mysql 存储过程 带 out 返回值,返回刚插入数据库中的自增的ID,LAST_INSERT_ID() 的使用
    如何俘获一个 IT 男的心,让他成为男友然后变成老公?
    MySqlHelper.cs mysql数据库助手类
    mysql 按年度、季度、月度、周、日SQL统计查询,mysql 存储过程 中 in 和 FIND_IN_SET 传递多个参数的使用
    奇怪的母版页里面的 form 表单里面的 enctype="multipart/formdata" html控件上传 FileUpload控件上传 一次多图片上传
    asp.net 连接 Mysql 代码生成器(下载地址)
    Convert.ToInt32、(int)和int.Parse,int.TryParse四者之间的区别:
    在web项目中 使用 WebService 根据IP地址来源搜索实际物理地址,常用的WebServices
    vc6控制台程序利用SoapToolkit3.0调用WebService
    浅议C++/CLI的gcnew关键字
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/7220554.html
Copyright © 2011-2022 走看看