Python 常用魔法方法
1.dict
无处不在的__dict__
类的__dict__属性和类对象的__dict__属性
# -*- coding: utf-8 -*-class A(object):"""Class A."""a = 0b = 1def __init__(self):self.a = 2self.b = 3def test(self):print('a normal func.')@staticmethoddef static_test(self):print('a static func.')@classmethoddef class_test(self):print('a calss func.')obj = A()
print(A.__dict__)
print(obj.__dict__)
运行结果如下
{'__module__': '__main__', '__doc__': '\n Class A.\n ', 'a': 0, 'b': 1, '__init__': <function A.__init__ at 0x7f2fd92a0268>, 'test': <function A.test at 0x7f2fcabf3ea0>, 'static_test': <staticmethod object at 0x7f2fd9299ba8>, 'class_test': <classmethod object at 0x7f2fd9299c88>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>}
{'a': 2, 'b': 3}
由此可见, 类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类__dict__里的;
对象的__dict__中存储了一些self.xxx的一些东西.
Python里什么没有__dict__属性
虽然说一切皆对象,但对象也有不同,就好比不是每个人的女朋友都是一个人一样,一些内置的数据类型是没有__dict__属性的.
int, list, dict等这些常用的数据类型是没有__dict__属性的,其实这是可预料的,就算给了它们dict属性也没啥用,毕竟它们只是用来做数据容器的。
发生继承时候的__dict__属性
子类有自己的__dict__, 父类也有自己的__dict__,子类的全局变量和函数放在子类的dict中,父类的放在父类dict中。
总结:
1) 内置的数据类型没有__dict__属性
2) 每个类有自己的__dict__属性,就算存着继承关系,父类的__dict__ 并不会影响子类的__dict__
3) 对象也有自己的__dict__属性, 存储self.xxx 信息,父子类对象公用__dict__
2. 构造方法
我们最为熟知的基本的魔法方法就是__init__ ,我们可以用它来指明一个对象初始化的行为。然而,当我们调用 x = SomeClass() 的时候__init__ 并不是第一个被调用的方法。事实上,第一个被调用的是__new__ ,这个 方法才真正地创建了实例。当这个对象的生命周期结束的时候,__del__会被调用。让我们近一步理解这三个方法:
__new__(cls,[...)
__new__ 是对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 __init__ 。 __new__ 很少使用,但是也有它适合的场景,尤其是当类继承自一个像元组或者字符串这样不经常改变的类型的时候。我不打算深入讨论__new__ ,因为它并不是很有用, Python文档 中 有详细的说明。__init__(self,[...])
类的初始化方法。它获取任何传给构造器的参数(比如我们调用 x = SomeClass(10, ‘foo’) , __init__ 就会接到参数 10 和 ‘foo’ 。__init__在Python的类定义中用的最多。__del__(self)
__new__ 和 __init__ 是对象的构造器, __del__ 是对象的销毁器。它并非实现了语句 del x (因此该语句不等同于 x.__del__())。而是定义了当对象被垃圾回收时的行为。 当对象需要在销毁时做一些处理的时候这个方法很有用,比如 socket 对象、文件对象。但是需要注意的是,当Python解释器退出但对象仍然存活的时候, __del__ 并不会 执行。 所以养成一个手工清理的好习惯是很重要的,比如及时关闭连接。
3.操作符
比较操作符
Python包含了一系列的魔法方法,用于实现对象之间直接比较,而不需要采用方法调用。同样也可以重载Python默认的比较方法,改变它们的行为。下面是这些方法的列表:
__cmp__(self, other)
__cmp__ 是所有比较魔法方法中最基础的一个,它实际上定义了所有比较操作符的行为(<,==,!=,等等),但是它可能不能按照你需要的方式工作(例如,判断一个实例和另一个实例是否相等采用一套标准,而与判断一个实例是否大于另一实例采用另一套)。 __cmp__ 应该在 self < other 时返回一个负整数,在self == other 时返回0,在 self > other 时返回正整数。最好只定义你所需要的比较形式,而不是一次定义全部。 如果你需要实现所有的比较形式,而且它们的判断标准类似,那么 __cmp__ 是一个很好的方法,可以减少代码重复,让代码更简洁。__eq__`(self, other)
定义等于操作符(==)的行为。__ne__(self, other)
定义不等于操作符(!=)的行为。__lt__(self, other)
定义小于操作符(<)的行为。__gt__(self, other)
定义大于操作符(>)的行为。__le__(self, other)
定义小于等于操作符(<)的行为。__ge__(self, other)
定义大于等于操作符(>)的行为。
算数操作符
数值操作符
这里把它们分成了五类:一元操作符,常见算数操作符,反射算数操作符(后面会涉及更多),增强赋值操作符,和类型转换操作符。以一元操作符和常见算数操作符举例.
一元操作符
一元操作符只有一个操作符。
__pos__(self)
实现取正操作,例如 +some_object。__neg__(self)
实现取负操作,例如 -some_object。__abs__(self)
实现内建绝对值函数 abs() 操作。__invert__(self)
实现取反操作符 ~。__round__(self, n)
实现内建函数 round() ,n 是近似小数点的位数。__floor__(self)
实现 math.floor() 函数,即向下取整。__ceil__(self)
实现 math.ceil() 函数,即向上取整。__trunc__(self)
实现 math.trunc() 函数,即距离零最近的整数。
常见算数操作符
__add__(self, other)
实现加法操作。__sub__(self, other)
实现减法操作。
__mul__(self, other)
实现乘法操作。__floordiv__(self, other)
实现使用 // 操作符的整数除法。__div__(self, other)
实现使用 / 操作符的除法。__truediv__(self, other)
实现 true 除法,这个函数只有使用 from __future__ import division 时才有作用。__mod__(self, other)
实现 % 取余操作。__divmod__(self, other)
实现 divmod 内建函数。__pow__
实现 ** 操作符。__lshift__(self, other)
实现左移位运算符 << 。__rshift__(self, other)
实现右移位运算符 >> 。__and__(self, other)
实现按位与运算符 & 。__or__(self, other)
实现按位或运算符 | 。__xor__(self, other)
实现按位异或运算符 ^ 。
4. 类的表示
__str__(self)
定义对类的实例调用 str() 时的行为。__repr__(self)
定义对类的实例调用 repr() 时的行为。 str() 和 repr() 最主要的差别在于“目标用户”。 repr() 的作用是产生机器可读的输出(大部分情况下,其输出可以作为有效的Python代码),而 str() 则产生人类可读的输出。__format__(self)
定义当类的实例用于新式字符串格式化时的行为,例如,“Hello, 0:abc!”.format(a) 会导致调用 a.__format__(“abc”) 。当定义你自己的数值类型或字符串类型时,你可能想提供某些特殊的格式化选项,这种情况下这个魔法方法会非常有用。__dir__(self)
定义对类的实例调用 dir() 时的行为,这个方法应该向调用者返回一个属性列表。一般来说,没必要自己实现 __dir__ 。但是如果你重定义了 __getattr__或者 __getattribute__ (下个部分会介绍),乃至使用动态生成的属性,以实现类的交互式使用,那么这个魔法方法是必不可少的。到这里,我们基本上已经结束了魔法方法指南中无聊并且例子匮乏的部分。既然我们已经介绍了较为基础的魔法方法,是时候涉及更高级的内容了。
5. 访问控制
很多从其他语言转向Python的人都抱怨Python的类缺少真正意义上的封装(即没办法定义私有属性然后使用公有的getter和setter)。然而事实并非如此。实际上Python不是通过显式定义的字段和方法修改器,而是通过魔法方法实现了一系列的封装。
__getattr__(self, name)
当用户试图访问一个根本不存在(或者暂时不存在)的属性时,你可以通过这个魔法方法来定义类的行为。这个可以用于捕捉错误的拼写并且给出指引,使用废弃属性时给出警告(如果你愿意,仍然可以计算并且返回该属性),以及灵活地处理AttributeError。只有当试图访问不存在的属性时它才会被调用,所以这不能算是一个真正的封装的办法。__setattr__(self, name, value)
和 __getattr__ 不同, __setattr__ 可以用于真正意义上的封装。它允许你自定义某个属性的赋值行为,不管这个属性存在与否,也就是说你可以对任意属性的任何变化都定义自己的规则。然后,一定要小心使用 __setattr__ ,这个列表最后的例子中会有所展示。__delattr__(self, name)
这个魔法方法和 setattr 几乎相同,只不过它是用于处理删除属性时的行为。和 setattr_ 一样,使用它时也需要多加小心,防止产生无限递归(在__delattr__ 的实现中调用 del self.name 会导致无限递归)。__getattribute__(self, name)
__getattribute__
看起来和上面那些方法很合得来,但是最好不要使用它。__getattribute__ 只能用于新式类。在最新版的Python中所有的类都是新式类,在老版Python中你可以通过继承 object 来创建新式类。 __getattribute__ 允许你自定义属性被访问时的行为,它也同样可能遇到无限递归问题(通过调用基类的__getattribute__ 来避免)。__getattribute__ 基本上可以替代 __getattr__ 。只有当它被实现,并且显式地被调用,或者产生 AttributeError 时它才被使用。 这个魔法方法可以被使用(毕竟,选择权在你自己),我不推荐你使用它,因为它的使用范围相对有限(通常我们想要在赋值时进行特殊操作,而不是取值时),而且实现这个方法很容易出现Bug。
部分内容参考此处:Python魔法方法指南
Python 常用魔法方法相关推荐
- python 魔法方法常用_Python 常用魔法方法(下)
Python 常用魔法方法(下) 回顾 魔法方法是 Python 内置方法, 不需要我们手动调用, 它存在的目的是给 解释器 调用的. 比如我们在写 "1 + 1 " 的时候, 这 ...
- python __reduce__魔法方法_Python魔法方法指南
(译)Python魔法方法指南 简介 本指南归纳于我的几个月的博客,主题是 魔法方法 . 什么是魔法方法呢?它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加"魔法" ...
- Python之魔法方法详解
转载于: https://pyzh.readthedocs.io/en/latest/python-magic-methods-guide.html 11.1. 简介 本指南归纳于我的几个月的博客,主 ...
- Python基础——魔法方法(一)
文章目录 魔法方法 构造和析构 算数运算 算数操作符 反运算 增量赋值运算 一元操作符 属性访问 魔法方法 前面在介绍类和对象时,已经接触过Python常用的魔法方法,那么什么是魔法方法呢? 魔法方法 ...
- Python常见魔法方法详解
目录 常用魔法方法 1. `__str__()` 2. `__del__()` 3. `__call__()` 4. `__new__()` 5. `__del__()` 6. `__init__() ...
- python魔法方法学不懂_深入学习Python之魔法方法
什么是Python魔法方法 魔法方法就如同它的名字一样神奇,总能在你需要的时候为你提供某种方法来让你的想法实现.魔法方法是指Python内部已经包含的,被双下划线所包围的方法,这些方法在进行特定的操作 ...
- 一木.溪桥学Python-13:多继承、多态、常用魔法方法、单例模式
一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-13:多继承 ...
- 一篇文章带你读懂Python的魔法方法
作者:Python进阶者 来源:Python爬虫与数据挖掘 今 日 鸡 汤 燕雀安知鸿鹄之志哉? /1 前言/ 魔法方法是python 里面非常重要的一个分支,平时我们写代码或多或少都会接触到他们,而 ...
- Python的魔法方法总结
转自:http://pyzh.readthedocs.io/en/latest/python-magic-methods-guide.html 原文: http://www.rafekettler.c ...
最新文章
- Ubuntu 16.04 安装 caffe
- 定制zabbix的rpm包---spec文件的书写
- jsp uri=http://java.sun.com/jsp/jstl/core报错解决
- 65%的家庭有人“啃老”,数据解读国内版巨婴是如何炼成的?
- ways to talk with girls
- Saltstack SLS文件解读
- html 输出不了php,html不打印输出文本
- idea连接sqlite
- linux firefox严重卡顿,Firefox火狐浏览器出现卡顿崩溃等问题的解决方法
- 常见微商升级、返利制度设计详解
- pythongui界面管理系统_Python实现GUI学生信息管理系统
- python polygon_python – Polygon.contains和Polygon.within有什么区别?
- CGB2106-Day13
- 你们要的线上GC问题案例来啦
- Cisco路由器配置教程
- 计算机ata证书的定义及用处介绍
- 英语期刊写作-通往国际学术舞台的阶梯期末
- 转-4年!我对OpenStack运维架构的总结
- 线性代数(14)——正交性、标准正交基和投影
- ubuntu 命令打开html文件
热门文章
- linux 笔记本 显卡驱动下载地址,linux笔记本上安装了双显卡驱动(intel+nvidia)
- java 访问linux 根目录_paip兼容windows与linux的java类根目录路径的方法
- taro+vue3 搭建一套框架,适用于微信小程序和H5
- 三星Note3预览图片与浮窗指令使用技巧
- Android 简单工厂模式
- CE修改器-CE修改器下载
- 免费版Typora设置vue主题
- 大数据机器学习是什么,主要能应用到哪些领域?
- 分区 读取参数错误_如何修复“警告:重新读取分区表失败,错误22:参数无效”在Linux上错误...
- VBoxManage 命令行安装虚拟机