接上文,再介绍最后几个常用的魔法方法。

关于__dict__:

先上个例子:

class Test(object):
fly = True def __init__(self, age):
self.age = age

__dict__魔法方法可以被称为系统,他是存储各分层属性的魔法方法。__dict__中,键为属性名,值为属性本身。可以这样理解,在平时我们给类和实例定义的那些属性,都会被存储到__dict__方法中用于读取。而我们平时使用的类似这样的语法Test.fly 其实就是调用了类属性,同样可以写成Test.__dict__['fly']。除了类属性,还有实例属性。当我们用类实例化一个实例,例如上文我们使用p = Test(2)实例化类Test,p也会具有__dict__属性。这里会输出:

{'age': 2}

由上可以发现,python中的属性是进行分层定义的。/object/Test/p这样一层一层下来的。当我们需要调用某个属性的时候,python会一层一层往上面遍历上去。先从实例,然后实例的__class__的__dict__,然后是该类的__base__。这样__dict__一路找上去。如果最后都没有找到,就抛出AttributeError错误。

这里可以延伸一下,没记错的话,我前面有篇文章讲了一个方法__slot__。__slots__方法就是通过限制__dict__,只让类实例初始化__slots__里面定义的属性,而且让实例不再拥有__dict__方法,来达到节约内存的目的。我将会就上面的那个例子重写一下,来说明这个问题。

 class Test(object):
__slots__ = ['age'] fly = True def __init__(self, age):
self.age = age

output:

In [25]: Test.__dict__
Out[25]:
dict_proxy({'__doc__': None,
'__init__': <function __main__.__init__>,
'__module__': '__main__',
'__slots__': ['age'],
'age': <member 'age' of 'Test' objects>,
'fly': True}) In [36]: p.__dict__
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-36-3a1cec47d020> in <module>()
----> 1 p.__dict__ AttributeError: 'Test' object has no attribute '__dict__' In [37]: p.age
Out[37]: 3 In [38]: p.fly
Out[38]: True

可以看到,__slots__方法并没有阻止由下至上的属性查找方法,只是不会再允许没有包含在__slots__数组中的属性再被赋值给实例了。但这并不妨碍,继续调用允许访问的属性,以及类属性。

关于__get__, __set__, __del__:

在前面的文章里面我也介绍过这三个魔法方法,虽然一般是用不到的,但是在写库的时候它们有特别的用途。他们是python另外一个协议descriptor的根基。

同一个对象的不同属性之间可能存在依赖关系。当某个属性被修改时,我们希望依赖于该属性的其他属性也同时变化。在这种环境下面__dict__方法就无法办到。因为__dict__方法只能用来存储静态属性。python提供了多种即时生成属性的方法。其中一种就是property。property是特殊的属性。比如我们为上面的例子增加一个property特性,使得他能够动态变化。来看这个例子:

class Test(object):
fly = True def __init__(self, age):
self.age = age def whether_fly(self):
if self.age <= 30:
return True
else:
return False def just_try_try(self, other):
pass whether_fly = property(whether_fly) p = Test(20)
print p.age
print p.whether_fly
p.age = 40
print p.age
print p.whether_fly

output:

20
True
40
False

可以看到 我们可以使用这种手段,动态修改属性值。property有四个参数。前三个参数为函数,分别用于处理查询特性、修改特性、删除特性。最后一个参数为特性的文档,可以为一个字符串,起说明作用。这里我只是要到了第一个参数,查询的时候动态修改他的返回值,而第二个参数是在修改值的时候就会体现出来。

Reference:

http://www.cnblogs.com/vamei/archive/2012/12/11/2772448.html

Python魔法方法(magic method)细解几个常用魔法方法(下)的更多相关文章

  1. Python魔法方法(magic method)细解几个常用魔法方法(上)

    这里只分析几个可能会常用到的魔法方法,像__new__这种不常用的,用来做元类初始化的或者是__init__这种初始化使用的 每个人都会用的就不介绍了. 其实每个魔法方法都是在对内建方法的重写,和做像 ...

  2. Python魔术方法-Magic Method

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...

  3. 流动python - 什么是魔术方法(magic method)

    我们经常看到各种各样的方法已经被包围了由双下划线,例如__init__,他们是魔术方法. 魔术方法python语言预订好"协议",在不同情况下不同的魔术方法,是隐式调用.我们重写这 ...

  4. <转>详解DNS的常用记录(下):DNS系列之三

    在上篇博文中我们介绍了DNS服务器中几种不可或缺的记录,包括A记录,NS记录和SOA记录.本篇博文中我们将继续为大家介绍DNS的另外几种常用记录,希望能对大家了解DNS有所帮助. 四 MX记录 MX记 ...

  5. Python基础:面向对象基础 (一) 类及其属性和魔法方法

    定义类,添加和获取对象属性 # 定义类 格式如下 # class 类名: # 方法列表 # 新式类定义形式 # info 是一个实例方法,第一个参数一般是self,表示实例对象本身 class Her ...

  6. python类:magic魔术方法

    http://blog.csdn.net/pipisorry/article/details/50708812 魔术方法是面向对象Python语言中的一切.它们是你可以自定义并添加"魔法&q ...

  7. (转)python类:magic魔术方法

    原文:https://blog.csdn.net/pipisorry/article/details/50708812 版权声明:本文为博主皮皮http://blog.csdn.net/pipisor ...

  8. python字符串常用的方法解析

    这是本人在学习python过程中总结的一些关于字符串的常用的方法. 文中引用了python3.5版本内置的帮助文档,大致进行翻译,并添加了几个小实验. isalnum S.isalnum() -> ...

  9. OpenCV常用图像拼接方法(一) :直接拼接

    OpenCV常用图像拼接方法将分为四部分与大家分享,这里是第一种方法,欢迎关注后续. OpenCV常用图像拼接方法(一) :直接拼接,俗称硬拼,就是简单的将两张图片合并成一张大图. 方法比较简单,这里 ...

随机推荐

  1. centos7下安装docker(17.5docker监控的总结对比)

    到现在为止,我已经学习了docker自带的监控方案:ps/ls/top/stats,以及sysdig,weave scope,cadvisor,prometheus多种监控工具,现在做个总结和比较 部 ...

  2. tensorflow中的Supervisor

    tf.train.Supervisor()可以帮我们简化一些事情,可以保存模型参数和Summary,它有以下的作用: 1)自动去checkpoint加载数据或初始化数据 ,因此我们就不需要手动初始化或 ...

  3. python3 练习题 day03

    ''' 1. 文件a1.txt内容 序号 部门 人数 平均年龄 备注 1 python 30 26 单身狗 2 Linux 26 30 没对象 3 运营部 20 24 女生多 ....... 通过代码 ...

  4. 爬虫之selenium模拟点击

    在利用爬虫爬取页面HTML信息得时候有的当你运用request方法爬取时爬下来得HTML信息和网站信息不相符,这也导致以后得爬去无法进行,这也是反扒机制之一,解决办法时利用代码进行模拟网页点击,来爬去 ...

  5. redis学习(五)——Set数据类型

    一.概述 在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加.删除或判断某一元素是否存在等操作.需要说明的是,这些操作的时间复杂度为 ...

  6. SkylineGlobe TerraExplorer Pro 遇到模型显示有锯齿怎么办?

    SkylineGlobe TerraExplorer Pro 遇到模型显示有锯齿怎么办? 这个问题跟软件的版本无关,跟机器的显卡有关,看下面的截图: 试试看,祝你好运!

  7. UVA10838 The Pawn Chess

    UVA好题没人写系列,感觉可以稍稍练习一下面向对象编程的形式(大雾) 题意很简单,在国际象棋的棋盘中有一些兵,走到对方底线即为胜利,问最优决策下谁能获胜.并输出最小步数. 首先这里的棋盘都只有\(4\ ...

  8. SpringBoot整合Druid数据源

    关于SpringBoot数据源请参考我上一篇文章:https://www.cnblogs.com/yueshutong/p/9409295.html 一:Druid介绍 1. Druid是什么? Dr ...

  9. Node.js中读取文件后用Json.parse方法报错解决方案

    今天,在调试一个node项目时,发现了一个很大的坑,在此分享给大家! 大家都知道,Json.parse()方法对格式要求是很严格的,格式不对极其容易报错,但是有时候格式看似是正确的也会报错. 比如这一 ...

  10. 腾讯 Omi 5.0 发布 - Web 前端 MVVM 王者归来,mappingjs 强力加持

    写在前面 腾讯 Omi 框架正式发布 5.0,依然专注于 View,但是对 MVVM 架构更加友好的集成,彻底分离视图与业务逻辑的架构. 你可以通过 omi-cli 快速体验 MVVM: $ npm ...