1、__getattr__

当我们访问一个不存在的属性的时候,会抛出异常,提示我们不存在这个属性。而这个异常就是__getattr__方法抛出的,其原因在于他是访问一个不存在的属性的最后落脚点,作为异常抛出的地方提示出错再适合不过了。

看例子,我们找一个存在的属性和不存在的属性。

  1. class A(object):
  2. def __init__(self, value):
  3. self.value = value
  4.  
  5. def __getattr__(self, item):
  6. print "into __getattr__"
  7. return "can not find"
  8.  
  9. a = A(10)
  10. print a.value
  11. # 10
  12. print a.name
  13. # into __getattr__
  14. # can not find

可以看出,访问存在的属性时,会正常返回值,若该值不存在,则会进入最后的兜底函数__getattr__。

2、__setattr__

在对一个属性设置值的时候,会调用到这个函数,每个设置值的方式都会进入这个方法。

  1. class A(object):
  2. def __init__(self, value):
  3. print "into __init__"
  4. self.value = value
  5.  
  6. def __setattr__(self, name, value):
  7. print "into __setattr__"
  8. if value == 10:
  9. print "from __init__"
  10. object.__setattr__(self, name, value)
  11.  
  12.  
  13. a = A(10)
  14. # into __init__
  15. # into __setattr__
  16. # from __init__
  17. print a.value
  18. # 10
  19. a.value = 100
  20. # into __setattr__
  21. print a.value
  22. # 100

在实例化的时候,会进行初始化,在__init__里,对value的属性值进行了设置,这时候会调用__setattr__方法。

在对a.value重新设置值100的时候,会再次进入__setattr__方法。

需要注意的地方是,在重写__setattr__方法的时候千万不要重复调用造成死循环。

比如:

  1. class A(object):
  2. def __init__(self, value):
  3. self.value = value
  4.  
  5. def __setattr__(self, name, value):
  6. self.name = value

这是个死循环。当我们实例化这个类的时候,会进入__init__,然后对value进行设置值,设置值会进入__setattr__方法,而__setattr__方法里面又有一个self.name=value设置值的操作,会再次调用自身__setattr__,造成死循环。

除了上面调用object类的__setattr__避开死循环,还可以如下重写__setattr__避开循环。

  1. class A(object):
  2. def __init__(self, value):
  3. self.value = value
  4.  
  5. def __setattr__(self, name, value):
  6. self.__dict__[name] = value
  7.  
  8.  
  9. a = A(10)
  10. print a.value
  11. # 10

3、__delattr__

__delattr__是个删除属性的方法

  1. class A(object):
  2. def __init__(self, value):
  3. self.value = value
  4.  
  5. def __delattr__(self, item):
  6. object.__delattr__(self, item)
  7.  
  8. def __getattr__(self, item):
  9. return "when can not find attribute into __getattr__"
  10.  
  11.  
  12.  
  13. a = A(10)
  14. print a.value
  15. # 10
  16. del a.value
  17. print a.value
  18. # when can not find attribute into __getattr__

__delattr__也要避免死循环的问题,就如__setattr__一样,在重写__delattr__,避免重复调用。

 

类中的__getattr__ 与 __setattr__ 魔法方法的更多相关文章

  1. 第8章 Python类中常用的特殊变量和方法目录

    第8章 Python类中常用的特殊变量和方法 第8.1节 Python类的构造方法__init__深入剖析:语法释义 第8.2节 Python类的__init__方法深入剖析:构造方法案例详解 第8. ...

  2. 转载:java 中对类中的属性使用set/get方法的意义和用法

    经常看到有朋友提到类似:对类中的属性使用set/get方法的作用?理论的回答当然是封闭性之类的,但是这样对我们有什么作用呢?为什么要这样设计?我直接使用属性名来访问不是更直接,代码更简洁明了吗?下面我 ...

  3. C++:调整基类成员在派生类中的访问属性的其他方法(同名成员和访问声明)

    4.3 调整基类成员在派生类中的访问属性的其他方法 4.3.1 同名函数 在定义派生类的时候,C++语言允许在派生类中说明的成员与基类中的成员名字相同,也就是 说,派生类可以重新说明与基类成员同名的成 ...

  4. 在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出MethodArgumentNotValidException异常,因此,只需要在ExceptionHandler类中添加处理对应异常的方法即可。

    在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出Method ...

  5. 第8.34节 《Python类中常用的特殊变量和方法》总结

    本章介绍了Python类中常用的特殊变量和方法,这些特殊变量和方法都有特殊的用途,是Python强大功能的基石之一,许多功能非常有Python特色.由于Python中一切皆对象,理解这些特殊变量和方法 ...

  6. C#类中的字段、属性和方法

    C#类中的字段.属性和方法 刚开始学C#,对于类中的字段.属性和方法很难分清,写下这份笔记,帮助理解 字段:与类相关的变量 声明方法与声明变量类似,可在前面添加访问修饰符.static关键字等: 属性 ...

  7. 面向对象相关概念与在python中的面向对象知识(魔法方法+反射+元类+鸭子类型)

    面向对象知识 封装 封装的原理是,其成员变量代表对象的属性,方法代表这个对象的动作真正的封装是,经过深入的思考,做出良好的抽象(设计属性时用到),给出“完整且最小”的接口,并使得内部细节可以对外透明( ...

  8. python类与对象各个算数运算魔法方法总结

    1.python类与对象各个算术运算魔法方法总结: 2.各个魔法方法应用举例: 3.实例训练: (1)我们都知道在 Python 中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常 ...

  9. python中几个常见的魔法方法

    首先,什么是魔法方法呢?在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做"魔法"方法. __ init__()方法 当一个实例被创建的时候调用的初始 ...

随机推荐

  1. mysql按照时间分组查询

    mysql 按年.月.周.日分组查询 1.按照年份分组查询 SELECT DATE_FORMAT(t.bill_time,'%Y') month_time,sum(t.pay_price) total ...

  2. 生产环境上,哨兵模式集群Redis版本升级应用实战

    背景: 由于生产环境上所使用的Redis版本并不一致,好久也没有更新,为了避免版本不同对Redis集群造成影响,从而升级为统一Redis版本! 1.集群架构 一主两从三哨兵: 2.升级方案 (1)升级 ...

  3. Go Error 嵌套到底是怎么实现的?

    原文链接: Go Error 嵌套到底是怎么实现的? Go Error 的设计哲学是 「Errors Are Values」. 这句话应该怎么理解呢?翻译起来挺难的.不过从源码的角度来看,好像更容易理 ...

  4. manjora20使用体验

    #第一次评估 适合小白日常办公,不适合计算机研究人员 ##优点 稳定流畅,运行速度比Ubuntu快很多 界面优美,UI很好 强大的aur软件库应有尽有,几乎是所有软件都有 中国源和arch社区提供的包 ...

  5. http 的get 与 post 的区别

    1.原理区别 一般在浏览器中输入网址访问资源都是通过GET方式:在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认为GET提交 Http定义了与服务器交互的不同方法,最基本的 ...

  6. gin中绑定html复选框

    main.go package main import "github.com/gin-gonic/gin" type myForm struct { Colors []strin ...

  7. String类(获取,转换,判断,比较)

    1 package cn.itcast.p1.string.demo; 2 3 import java.util.Iterator; 4 5 import com.sun.org.apache.xpa ...

  8. 学习JAVAWEB第一天

    第一天:单元测试(junit)黑盒测试:不需要写代码,给输入值,看程序能否给出期望值白盒测试:需要写代码,关注程序的具体执行流程junit使用步骤:步骤1:定义一个测试类建议类名,被测试类名后面加一个 ...

  9. Uwl.Admin.Core开源框架(三) 使用RabbitMQ

    Uwl.Admin.Core中使用RabbitMQ消息队列: 本文负责讲解RabbitMQ的使用 Uwl.Admin.Core使用的技术有: *.Async和Await 异步编程 *.Reposito ...

  10. openstack horizon 学习(3) DataTable

    上一篇中粗略的讲了下openstack中horizon的dashboard和panel的添加,本打算在这章中对有关于pluggable settings中的配置做详细的总结,然放弃了这念头.原因是搞懂 ...