先介绍几个类中的应用__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集合之Properties

    Java集合之Properties

  2. javaSE_08Java中static、继承、重写

    一.Static 学习静态这个关键字,关键是抓住两个点: 1,关注其语法特点 2,关注其使用场景 案例讲解: 我们先从静态变量开始,当一个成员变量加上static修饰之后,会是一个什么效果? 比如创建 ...

  3. Chrome 开发者工具断点调试(视频教程)

    很多人不了解 Chrome Dev Tools (开发者工具)的使用方法和技巧. 其中很多技能,无论是前端开发从业者,还是普通用户,了解一些还是对日常很有帮助的. 本猿定期录制.甚至根据您的需求来订制 ...

  4. OSS web直传 ajax方式 上传图片、文件

    部分js代码 send_request = function(){//这是从后台获取认证策略等信息. var htmlobj=$.ajax({url:root+"/service/polic ...

  5. Backbox Linux简介与配置内网IP

    总体说起来,Backbox内置的工具什么的,并不是很多,但是它集成了一些用起来很棒的工具. 比如:Beef.Sqlmap.wpscan.zenmap.msf.w3af.dns嗅探等一系列工具,传说中的 ...

  6. Java模拟http请求调用远程接口工具类

    package ln; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamRea ...

  7. RMAN备份与恢复(二)--常用操作学习

    (1)连接目标数据库 在RMAN中可以建立与目标数据库或恢复目录数据库的连接.与目标数据库连接时,用户须具有sysdba系统权限,以保证可以进行数据库的备份.修复与恢复工作. 可以在操作系统命令提示符 ...

  8. 2017最新xcode打包APP详细图文

    网上的xcode打包ipa教程大多太旧而且又不完整,所以整理了一个最新的完整详细的xcode打包APP的图文教程分享给小白到大神路上前进的你我. xcode打包IPA包之前先申请iOS证书,然后导入证 ...

  9. Java8 Lambda/Stream使用说明

    一.Stream流1. 流的基本概念 1.1 什么是流?流是Java8引入的全新概念,它用来处理集合中的数据,暂且可以把它理解为一种高级集合.众所周知,集合操作非常麻烦,若要对集合进行筛选.投影,需要 ...

  10. hibernate 返回对象指定属性,需要返回的列,可以直接返回 对象属性

    // hibernate 返回对象指定属性,需要返回的列,可以直接返回 对象属性 @Override public TeamPlan getTeamPlanByBaoMingId(String bao ...