先介绍几个类中的应用__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.11\python.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.11\python.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.11\python.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.11\python.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.11\python.exe E:/py_prj/python_cookbook/chapter8.py
already exist
{'value1': 3, 'value': 'value'}
上面的代码中,首先判断赋值的对象是否已存在,如果存在则打印already exist
 

python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性的更多相关文章

  1. python cookbook第三版学习笔记十:类和对象(一)

    类和对象: 我们经常会对打印一个对象来得到对象的某些信息. class pair:     def __init__(self,x,y):         self.x=x         self. ...

  2. python cookbook第三版学习笔记十五:property和描述

    8.5 私有属性: 在python中,如果想将私有数据封装到类的实例上,有两种方法:1 单下划线.2 双下划线 1 单下划线一般认为是内部实现,但是如果想从外部访问的话也是可以的 2 双下划线是则无法 ...

  3. python cookbook第三版学习笔记十四:类和对象(五)代理类以及内存回收

    代理类: 代理类的作用其实有继承有些类似,如果你想将某个实例的属性访问代理到内部另外一个实例中去,可以用继承也可以用代理.来看下代理的应用: class A:     def spam(self,x) ...

  4. python cookbook第三版学习笔记十六:抽象基类

    假设一个工程中有多个类,每个类都通过__init__来初始化参数.但是可能有很多高度重复且样式相同的__init__.为了减少代码.我们可以将初始化数据结构的步骤归纳到一个单独的__init__函数中 ...

  5. python cookbook第三版学习笔记十九:未包装的函数添加参数

    比如有下面如下的代码,每个函数都需要判断debug的是否为True,而默认的debug为False def a(x,debug=False): if debug: print('calling a') ...

  6. python cookbook第三版学习笔记十八:可由用户修改的装饰器

    定义一个属性可由用户修改的装饰器: 在前面的介绍中使用装饰器来包装函数,这一章来介绍下如何让用户调整装饰器的属性. 首先来看下代码: from functools import wraps,parti ...

  7. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions

    The ideal time to catch an error is at compile time, before you even try to run the program. However ...

  8. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  9. 《Linux命令、编辑器与shell编程》第三版 学习笔记---002

    <Linux命令.编辑器与shell编程>第三版 学习笔记---001 Linux命令.编辑器与shell编程 Shell准备 1.识别Shell类型 echo  $0 echo $BAS ...

随机推荐

  1. Java中设计模式之单例设计模式-1

    单例作用 1 节省内存 2 可以避免多种状态导致状态冲突 单例的创建步骤 1 私有化构造方法 2 私有化声明的属性 3 getInstance 4 方法需要静态 单例分类 1.懒汉式 2.饿汉式 两种 ...

  2. Docker示例

    运行一个Hello world   zane@zane-V:~$ docker run ubuntu /bin/echo 'Hello world' Unable to find image 'ubu ...

  3. java数据结构(二叉树)

    Node节点: public class Node { public long data; public String sData; public Node leftChild; public Nod ...

  4. CSS浮动、绝对、相对定位

    浮动 float:属性{ float:none;    默认值,对象,不漂浮 float:left; 文本流向对象的右边 float:right; }; 清除浮动 clear:属性{ clear:no ...

  5. Linux SSH安全技巧

    SSH服务器配置文件是/etc/ssh/sshd_conf.在你对它进行每一次改动后都需要重新启动SSH服务,以便让改动生效. 1.修改SSH监听端口默认情况下,SSH监听连接端口22,攻击者使用端口 ...

  6. for循环 重点题

    1.冒泡排序  (特别重要): <script type="text/javascript"> var attr=Array(); for(var i=0; i< ...

  7. Hibernate_Validator学习分享

    1.   Hibernate Validator介绍 1.1   背景 在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情.应用程序必须通过某种手段来确保输入进来的数据从 ...

  8. LoadRunner11_录制Oracle数据库脚本

    [oracle环境] ①oracle:无需在本地安装oracle,但是oracle的odbc驱动一定要装:(我的安装路径为 D:\oracle ).安装好后在环境变量 " Path &quo ...

  9. angular-ui-alert

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. Notepad++中过滤掉的正则方式

    2 => 'ashadv'3 => 'aogro'4 => 'aogs'5 => 'ashamw'6 => 'arc'8 => 'gtsatq'9 => 'b ...