在以前的文章中,我聊过了Python的 __getitem__ 和 __setitem__ 方法。这些方法被称为“魔法”方法、特殊方法或者dunger方法(译者:国内书籍用“魔法”一词较多)。那么,什么是魔法方法呢?这正是今天我们要说的内容。

P.S.你会再一次的深深的爱上Python语言。

也将是一篇较长的文章,来让我们开始。

魔法方法究竟是什么?

魔法方法是一种具有特殊魅力的正常方法。Python通过这些魔法方法可以赋予你的class魔力。这些魔法方法都是以双下划线(__)作为前缀和后缀。坦率的讲,其实这些方法并没有什么魔法,另外这些方法这Python的文档中也没有较为详细的介绍,因此,今天我们就来详细的看一看这些方法

魔法方法之初始化

所有的Python开发者都知道,__init__()是一个类(class)的第一个方法,也可以叫做构造函数。虽然,__init__()方法是第一个被创建的,但是它却不是第一个被调用的执行的,__new__()方法才是最早被调用的方法。

  • __new__()方法:先读取参数,如:类名称,args,和kwargs。然后,__new__()方法把这些参数传递给对类名称的__init__()方法。

    语法:__new__(class_name, args, kwargs)

  • __init__()方法:是类的初始化方法或构造方法,这也几乎用于全局的初始化目的。

    语法:__init__(self, args, kwargs)

  • __del__()方法:类的析构函数。切记,这并不是定义del x,而是定义了一个对象被垃圾回收的行为。

    语法:__del__(self)

看一个例子:

class SimpleInit(object):
'''
Class to initialize a list with a value
'''
def __init__(self, value=10):
self._list = [value] def __del__(self):
del self._list

  

魔法方法之算术运算

算术运算是非常常见的,因此,如果你想创建属于自己的数据结构,魔法方法会使你的实现更容易。例如:我们可以像这样,some_list + some_list2,实现Python的列表(list)拼接。类似这种的有趣行为,我们可以通过魔法方法的算术运算实现定义。

  • __add__(self, other) 定义加法 (+)

  • __sub__(self, other) 定义减法 (-)

  • __mul__(self, other) 定义乘法 (*)

  • __floordiv__(self, other) 定义整除法 (//)

  • __div__(self, other) 定义浮点型除法 (/)

  • __mod__(self, other) 定义取余模运算 (%)

  • __and__(self, other) 定义按位与 (&)

  • __or__(self, other) 定义按位或 (|)

  • __xor__(self, other) 定义按位异或 (^)

  • __pow__(self, other) 定义指数运算 (**)

  • __lshift__(self, other) 定义按位左移 (<<)

  • __rshift__(self, other) 定义按位右移 (>>)

例如:

class SimpleAdder(object):
def __init__(self, elements=[]):
self._list = elements def __add__(self, other):
return self._list + other._list def __str__(self):
return str(self._list)
a = SimpleAdder(elements=[1,2,3,4])b = SimpleAdder(elements=[2, 3, 4])print(a + b) # [1, 2, 3, 4, 2, 3, 4]

  

魔法方法之增量赋值

Python不仅允许我们定义算术运算,也允许我们定义增量赋值运算。如果你不知道什么是增量赋值是什么?那么我们来看一个简单的例子:

x = 5
x += 1 # This first adds 5 and 1 and then assigns it back to 'x'

因此有的时候,你可能想写一些自自定义逻辑实现增量赋值操作。魔法方法支持的运算符有:

  • __iadd__(self, other) 定义加法 (+=)

  • __isub__(self, other) 定义减法 (-=)

  • __imul__(self, other) 定义乘法 (*=)

  • __ifloordiv__(self, other) 定义整除法 (//=)

  • __idiv__(self, other) 定义浮点型除法 (/=)

  • __imod__(self, other) 定义取模运算 (%=)

  • __iand__(self, other) 定义按位与 (&=)

  • __ior__(self, other) 定义按位或 (|=)

  • __ixor__(self, other) 定义按位异或(^=)

  • __ipow__(self, other) 定义指数运算 (**=)

  • __ilshift__(self, other) 定义按位左移 (<<=)

  • __irshift__(self, other) 定义按位右移 (>>=)

魔法方法之比较运算

Python有一组广泛的魔术方法实现比较。我们可以覆盖默认的比较行为,来定义使用对象的引用方法。下面是比较魔法方法的列表:

  • __eq__(self, other) 帮助检查两个对象的相等。它定义了相等运算 (==)

  • __ne__(self, other) 定义了不等运算 (!=)

  • __lt__(self, other) 定义了小于运算 (<)

  • __gt__(self, other) 定义了大于运算 (>)

  • __le__(self, other) 定义了小于等于运算 (<=)

  • __ge__(self, other) 定义了大于等于运算 (>=)

例如:

class WordCounter(object):
'''
Simple class to count number of words in a sentence
'''
def __init__(self, sentence):
# split the sentence on ' '
if type(sentence) != str:
raise TypeError('The sentence should be of type str and not {}'.format(type(sentence)))
self.sentence = sentence.split(' ')
self.count = len(self.sentence) def __eq__(self, other_class_name):
'''
Check the equality w.r.t length of the list with other class
'''
return self.count == other_class_name.count def __lt__(self, other_class_name):
'''
Check the less-than w.r.t length of the list with other class
'''
return self.count < other_class_name.count def __gt__(self, other_class_name):
'''
Check the greater-than w.r.t length of the list with other class
'''
return self.count > other_class_name.count
word = WordCounter('Omkar Pathak')print(word.count)

  

魔法方法之类型转换

很多时候开发人员需要隐性的转换变量类型,来满足最要想要的结果。Python是关心你内在数据的类型的一种动态类型语言,除此之外,Python也关心你,哈哈!如果你想要自定义属于自己的方法,可以借助如下方法:

  • __int__(self) 定义类型转化为 int

  • __long__(self) 定义类型转化为 long

  • __float__(self) 定义类型转化为 float

  • __complex__(self) 定义类型转化为 complex(复数)

  • __oct__(self) 定义类型转化为 octal(八进制)

  • __hex__(self) 定义类型转化为 (十六进制)

  • __index__(self) 定义类型转化为一种int, 当对象被用于切片表达式( a slice expression)时

最常用的魔法方法

这里有一些魔法方法你应该经常遇到:

  • __str__(self) 定义了str()行为。例如,当你调用print(object_name),无论object_name是什么都会被__str__()执行

  • __repr__(self) 定义了repr()行为。这个很大程度上类似于__str__()。这两个之间的主要区别是,str()主要是人类可读的和repr()是机器可读的

  • __hash__(self) 定义了行为调用hash()

  • __len__(self) 返回容器的长度

  • __getitem__(self) 和 __setitem__(self). 更多内容可以详见我以前的博客文章。

  • __delitem__(self, key) 定义了一个删除一个项目的行为. 例如, del _list[3]

  • __iter__(self) 返回一个迭代容器

class CustomList(object):
def __init__(self, elements=0):
self.my_custom_list = [0] * elements def __str__(self):
return str(self.my_custom_list) def __setitem__(self, index, value):
self.my_custom_list[index] = value def __getitem__(self, index):
return "Hey you are accessing {} element whose value is: {}".format(index, self.my_custom_list[index]) def __iter__(self):
return iter(self.my_custom_list)obj = CustomList(12)obj[0] = 1print(obj[0])print(obj)

coding 快乐!

  

Python 的 “Magic” 方法的更多相关文章

  1. Python 的 Magic Methods 指南(转)

    介绍 本指南是数月博客的总结.主题是魔术方法. 什么是魔术方法呢?它们是面向对象Python语言中的一切.它们是你可以自定义并添加“魔法”到类中的特殊方法.它们被双下划线环绕(比如__init__或_ ...

  2. python的魔术方法大全

    在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”(魔术方法),例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中有相应描述,这 ...

  3. Python测试函数的方法之一

    Python测试函数的方法之一 首先介绍简单的try......except尝试运行的放例如下面的图和代码来简单介绍下: 注释:提醒以下代码环境为2.7.x 请3.x以上的同学们老规矩print(把打 ...

  4. 使用python原生的方法实现发送email

    使用python原生的方法实现发送email import smtplib from email.mime.text import MIMEText from email.mime.multipart ...

  5. Python中sorted()方法

    Python中sorted()方法的用法 1.先说一下iterable,中文意思是迭代器. Python的帮助文档中对iterable的解释是:iteralbe指的是能够一次返回它的一个成员的对象.i ...

  6. python类及其方法

    python类及其方法 一.介绍 在 Python 中,面向对象编程主要有两个主题,就是类和类实例类与实例:类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中 ...

  7. Python内置方法的时间复杂度(转)

    原文:http://www.orangecube.net/python-time-complexity 本文翻译自Python Wiki本文基于GPL v2协议,转载请保留此协议. 本页面涵盖了Pyt ...

  8. Python LOGGING使用方法

    Python LOGGING使用方法 1. 简介 使用场景 场景 适合使用的方法 在终端输出程序或脚本的使用方法 print 报告一个事件的发生(例如状态的修改) logging.info()或log ...

  9. [Python]读写文件方法

    http://www.cnblogs.com/lovebread/archive/2009/12/24/1631108.html [Python]读写文件方法 http://www.cnblogs.c ...

随机推荐

  1. 【日常训练】Hockey(CodeForces-96C)

    题意与分析 对于这题题意的理解比较重要,因为这是一条傻逼题: 大小写保持不变 原串中出现的非法字符串里的每一个字符都要替换 Lucky Letter越多越好 这样一种情况下,算法其实特别简单.我傻逼在 ...

  2. 通过Jmeter对Dubbo接口进行接口及性能测试

    dubbo接口/性能测试 dubbo简介 zookeeper简介.安装及配置 dubbo服务端demo dubbo客户端调用 jmeter工程改造及接口调用 读取jmeter参数用于dubbo性能测试 ...

  3. 《Python 网络爬虫权威指南》 分享 pdf下载

    链接:https://pan.baidu.com/s/1ZYEinjOwM_5dBIVftN42tg 提取码:1om6

  4. Shader Variants 打包遇到的问题

    1. 遇到的问题 最常见的是打包到手机后效果与PC上不一致,具体情况比如: 光照贴图失效 雾失效 透明或者cutoff失效 以上首先需要检查的地方是Shader变体的编译设置 2. 超级着色器编译成N ...

  5. 《杜增强讲Unity之Tanks坦克大战》3-添加坦克

    3 添加坦克 3.1 本节效果预览   3.2 另存新场景 首先打开上次的场景s1,另存为s2,放到同一个文件夹下面.   3.3 添加坦克模型 在Model文件夹下面找到Tank模型   将Tank ...

  6. UNITY_委托和事件

    UNITY_委托和事件 参考资料: Unity3D脚本编程-使用C#语言开发跨平台游戏-陈嘉栋 观察者模式 主题(Subject)管理某些数据,当主题的数据发生改变时,会通知已经注册(Register ...

  7. Ubuntu解压zip包中文乱码

    解决方法:通过unar 工具解压 步骤一: 安装unar: sudo apt-get install unrar 步骤二: 解压(以test.zip为例):unar test.zip 解压成功,乱码问 ...

  8. Hyperledger Fabric 1.2 --- Chaincode Operator 解读和测试(一)

    前言 本文主要目的是用于整理Hyperledger  Fabric中关于chaincode 管理和操作的内容,作者以release-1.2为范本进行讲解. 主要参考链接: https://hyperl ...

  9. 如何防范和应对Redis勒索,腾讯云教你出招

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB发表于云+社区专栏 9月10日下午,又一起规模化利用Redis未授权访问漏洞攻击数据库的事件发生,此次 ...

  10. 学习笔记 | Github

    Github教程 \(Github\)是个好东西QwQ 存代码不用U盘爸爸妈妈再也不用担心我的U盘弄丢没有备份啦! 创建github账号 创建仓库 输入命令 git clone https://git ...