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. 关于vue部署到nginx服务下,非根目录,刷新页面404的问题

    如果在根目录则添加 try_files $uri $uri/ /index.html; 如果不在根目录则添加,格式如下 location  /xxxx  { try_files $uri $uri/ ...

  2. div背景css样式笔记

    <style type="text/css"> .div1 { width: 1024px; height: 100%; margin: 0 auto; /*backg ...

  3. 【Java】二分法查找

    二分法查找 前提:所要查找的数组必须有序 public class Dichotomy { public static void main(String[] args) { int[] array = ...

  4. dubbo接口方法重载且入参未显式指定序列化id导致ClassCastException分析

    问题描述&模拟 线上登录接口,通过监控查看,有类型转换异常,具体报错如下图 此报错信息是dubbo consumer端显示,且登录大部分是正常,有少量部分会报类型转换异常,同事通过更换方法名+ ...

  5. 《剑指offer》面试题04. 二维数组中的查找

    问题描述 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 示例: ...

  6. 《剑指offer》面试题33. 二叉搜索树的后序遍历序列

    问题描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回 true,否则返回 false.假设输入的数组的任意两个数字都互不相同.   参考以下这颗二叉搜索树: 5 / \ ...

  7. 【感受】android + opencv + umat + opencl使用感受

    近期编译了android下支持opencl的opencv,使用opencl能力的关键是用cv::UMat替换cv::Mat. 实际使用后发现坑很多,非常不成熟,不推荐使用这种方式来提升实际产品的性能. ...

  8. 华为matebook x pro监听耳机电流声

    问题 左耳出现电流声,播放声音就电流声,关闭声音10s后才消失 设备 matebook x pro2018 hd206耳机 原因 matebook设计缺陷充电电流声大,毕竟早期type C快充,监听耳 ...

  9. 返回值Student处理过程

  10. IDEA包名分层问题

    解决办法: 将默认的"Hide empty Middle Packages"或者"compact middle packages"勾选项去掉,这样就不会把中间空 ...