先介绍几个类中的应用__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. 如何用Python做词云(收藏)

    看过之后你有什么感觉?想不想自己做一张出来? 如果你的答案是肯定的,我们就不要拖延了,今天就来一步步从零开始做个词云分析图.当然,做为基础的词云图,肯定比不上刚才那两张信息图酷炫.不过不要紧,好的开始 ...

  2. 用JQuery写的滚动条,可以改变样式哦!

    很早之前在做项目的时候要用到自定义的滚动条,可是现在的CSS2只能改改颜色什么的,对于改变形状或者更高级的用法根本不可能实现,没办法只能自己写一个了.(好像CSS3可以该形状,不过没研究过有兴趣的童鞋 ...

  3. APUE-文件和目录(五)函数rename和renameat

    rename和renameat #include <stdio.h> int rename(const char *oldname,const char*newname); int ren ...

  4. 用户权限模块之spring security

    准备工作:数据库采用mysql(5.6及以上) CREATE TABLE `auth_system` ( `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'I ...

  5. Hibernate入门(二)

    一 Hibernate使用注解 可以使用注解创建Hibernate程序,使用注解的优点是不用创建映射文件,直接创建对象的关联. 使用hibernate注解需要导入注解相关的JAR包. 1.下载JAR包 ...

  6. JavaScript练习笔记整理·3 - 6.25

    欢迎和大家一起来讨论~   基础练习(1):   我的解答为: function array_diff(a, b) { if (b == "") return a; return ...

  7. 开源框架GreenDao的操作

    1.为什么需要GreenDao?Google原生API不方便 @1手动组拼SQL语句 @2需要自己写操作数据库代码 @3不能把数据库中的数据映射成对象 @4没有实现关联查询 2.GreenDao是什么 ...

  8. EL表达式拼接字符串

    EL表达式拼接字符串<c:set var="types" value="${','}${resMap['vo'].lineType }${','}" &g ...

  9. javascript四舍五入tofixed

    //toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. $("#renjunlirun").val(zongLiRun.toFixed(2));//金额

  10. 9天C#转Java学习过程,自己记录一下

    其实没有完整的9天,就是连续每天花点时间,过程so frustrated,踩坑无数...下面是学习过程的记录 第1天 开始正式学习JavaEE,已完成: 1. Tomcat安装: 2. Tomcat配 ...