类中的__getattr__ 与 __setattr__ 魔法方法
1、__getattr__
当我们访问一个不存在的属性的时候,会抛出异常,提示我们不存在这个属性。而这个异常就是__getattr__方法抛出的,其原因在于他是访问一个不存在的属性的最后落脚点,作为异常抛出的地方提示出错再适合不过了。
看例子,我们找一个存在的属性和不存在的属性。
- class A(object):
- def __init__(self, value):
- self.value = value
- def __getattr__(self, item):
- print "into __getattr__"
- return "can not find"
- a = A(10)
- print a.value
- # 10
- print a.name
- # into __getattr__
- # can not find
可以看出,访问存在的属性时,会正常返回值,若该值不存在,则会进入最后的兜底函数__getattr__。
2、__setattr__
在对一个属性设置值的时候,会调用到这个函数,每个设置值的方式都会进入这个方法。
- class A(object):
- def __init__(self, value):
- print "into __init__"
- self.value = value
- def __setattr__(self, name, value):
- print "into __setattr__"
- if value == 10:
- print "from __init__"
- object.__setattr__(self, name, value)
- a = A(10)
- # into __init__
- # into __setattr__
- # from __init__
- print a.value
- # 10
- a.value = 100
- # into __setattr__
- print a.value
- # 100
在实例化的时候,会进行初始化,在__init__里,对value的属性值进行了设置,这时候会调用__setattr__方法。
在对a.value重新设置值100的时候,会再次进入__setattr__方法。
需要注意的地方是,在重写__setattr__方法的时候千万不要重复调用造成死循环。
比如:
- class A(object):
- def __init__(self, value):
- self.value = value
- def __setattr__(self, name, value):
- self.name = value
这是个死循环。当我们实例化这个类的时候,会进入__init__,然后对value进行设置值,设置值会进入__setattr__方法,而__setattr__方法里面又有一个self.name=value设置值的操作,会再次调用自身__setattr__,造成死循环。
除了上面调用object类的__setattr__避开死循环,还可以如下重写__setattr__避开循环。
- class A(object):
- def __init__(self, value):
- self.value = value
- def __setattr__(self, name, value):
- self.__dict__[name] = value
- a = A(10)
- print a.value
- # 10
3、__delattr__
__delattr__是个删除属性的方法
- class A(object):
- def __init__(self, value):
- self.value = value
- def __delattr__(self, item):
- object.__delattr__(self, item)
- def __getattr__(self, item):
- return "when can not find attribute into __getattr__"
- a = A(10)
- print a.value
- # 10
- del a.value
- print a.value
- # when can not find attribute into __getattr__
__delattr__也要避免死循环的问题,就如__setattr__一样,在重写__delattr__,避免重复调用。
类中的__getattr__ 与 __setattr__ 魔法方法的更多相关文章
- 第8章 Python类中常用的特殊变量和方法目录
第8章 Python类中常用的特殊变量和方法 第8.1节 Python类的构造方法__init__深入剖析:语法释义 第8.2节 Python类的__init__方法深入剖析:构造方法案例详解 第8. ...
- 转载:java 中对类中的属性使用set/get方法的意义和用法
经常看到有朋友提到类似:对类中的属性使用set/get方法的作用?理论的回答当然是封闭性之类的,但是这样对我们有什么作用呢?为什么要这样设计?我直接使用属性名来访问不是更直接,代码更简洁明了吗?下面我 ...
- C++:调整基类成员在派生类中的访问属性的其他方法(同名成员和访问声明)
4.3 调整基类成员在派生类中的访问属性的其他方法 4.3.1 同名函数 在定义派生类的时候,C++语言允许在派生类中说明的成员与基类中的成员名字相同,也就是 说,派生类可以重新说明与基类成员同名的成 ...
- 在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出MethodArgumentNotValidException异常,因此,只需要在ExceptionHandler类中添加处理对应异常的方法即可。
在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出Method ...
- 第8.34节 《Python类中常用的特殊变量和方法》总结
本章介绍了Python类中常用的特殊变量和方法,这些特殊变量和方法都有特殊的用途,是Python强大功能的基石之一,许多功能非常有Python特色.由于Python中一切皆对象,理解这些特殊变量和方法 ...
- C#类中的字段、属性和方法
C#类中的字段.属性和方法 刚开始学C#,对于类中的字段.属性和方法很难分清,写下这份笔记,帮助理解 字段:与类相关的变量 声明方法与声明变量类似,可在前面添加访问修饰符.static关键字等: 属性 ...
- 面向对象相关概念与在python中的面向对象知识(魔法方法+反射+元类+鸭子类型)
面向对象知识 封装 封装的原理是,其成员变量代表对象的属性,方法代表这个对象的动作真正的封装是,经过深入的思考,做出良好的抽象(设计属性时用到),给出“完整且最小”的接口,并使得内部细节可以对外透明( ...
- python类与对象各个算数运算魔法方法总结
1.python类与对象各个算术运算魔法方法总结: 2.各个魔法方法应用举例: 3.实例训练: (1)我们都知道在 Python 中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常 ...
- python中几个常见的魔法方法
首先,什么是魔法方法呢?在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做"魔法"方法. __ init__()方法 当一个实例被创建的时候调用的初始 ...
随机推荐
- linux安全篇:禁止频繁访问的ip访问nginx
实验环境 版本:redhat6.5ip:172.16.1.100,172.16.10软件:nginx 172.16.1.10部署nginx [root@localhost tools]# lsngin ...
- 18张图,详解SpringBoot解析yml全流程
原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 前几天的时候,项目里有一个需求,需要一个开关控制代码中是否执行一段逻辑,于是理所当然的在yml文件中配置了一个属性作为开关,再配合nacos就可 ...
- Web开发之HTTP协议
HTTP响应消息 一个HTTP响应代表服务器向客户端回送的数据. 一个完整的HTTP响应包括如下内容: 一个状态行.若干消息头.以及响应正文,其中的一些消息头和正文都是可选的,消息头和正文内容之间要用 ...
- java之类的抽取与对象的创建
Java语言之类的抽取 前言:世界由什么组成?This is a question.有人说是原子.分子,有人说是山川草木. 诚然,一千个人眼中有一千个哈姆雷特.而在程序员眼中,万物皆对象. 定义: 在 ...
- porcupine语音唤醒python实现
note it is not for arm pyaudio <= 3.6 version porcupine 3.5 3.6 not 3.7 code import struct import ...
- 第57篇-profile实例
之前已经介绍过回边计数和ProfileData与Layout,下面举个具体的例子看下MethodData是怎么利用ProfileData等记录详细的运行时信息的.实例如下: package com.t ...
- GitHub pages+自定义域名(腾讯云域名)+cloudflare加速
本人也是第一次走完整个流程,github pages当然一直有使用,创建也很简单,并且网上教程也比较多:然后是关于自定义域名的问题,自己以前使用过国外的免费域名,然后是直接修改就ok了,然后这次使用了 ...
- python 求模运算符--判断奇偶数
#!/usr/bin/python #coding=utf-8 #好好学习,天天向上 number = input("please enter a number:") number ...
- 删除文件行末尾的^M符号方法
有时发现某些文件的末尾总是带有^M符号 cat /etc/hosts.allow|col -b > /etc/hosts.allow.old
- Java枚举类在生产环境中的使用方式
前言 Java枚举在项目中使用非常普遍,许多人在做项目时,一定会遇到要维护某些业务场景状态的时候,往往会定义一个常量类,然后添加业务场景相关的状态常量.但实际上,生产环境的项目中业务状态的定义大部 ...