前言

python有众多的魔法方法,它们会在满足某种条件下触发执行,掌握好魔法方法的使用,可以加快程序的运行效率,同时减少逻辑调用。

关键字与魔法方法

python的一些魔法方法是关键字触发的,即python解释器遇到某个关键字就会去执行相应的魔法方法。

del与__del__

如果一个对象定义了__del__魔法方法,那么解释器会调用del关键字后对象的__del__魔法方法,然后在上下文中删除该对象。

class Dog(object):
def __init__(self):
pass
def __del__(self):
print('delete the dog object') dog = Dog()
del dog # 等价于 dog.__del__()

注意__del__魔法方法做的工作不是删除dog对象,而是在删除dog对象发生之前调用,是删除之前的钩子。

with与__enter__、__exit__

如果一个类实现了_enter_、__exit__魔法方法,我们就说这个类实现了一个上下文管理器,它使用with关键字触发,更多的用法参考:python之上下文管理器

if与__bool__

一个对象定义了__bool__魔法方法后,if关键字会触发该魔法方法,如果没有定义就会使用解释器预置的处理算法。

class List(list):
def __bool__(self):
print('list bool')
return True
if __name__ == "__main__":
ls = List([])
if ls: # 为真,等价于bool(ls)
print('mmm')

in\not in与__contains__

当使用in或not in关键字判断一个容器里的元素时,触发该容器的_contains_,如果没有定义,Python就会迭代整个序列.

class MyList(list):
def __contains__(self, item):
print('__contains__')
return super().__contains__(item) # 返回True或False if __name__ == "__main__":
my = MyList([1,2,3])
if 1 in my: # 等价于 bool(my.__contains__(1))
pass

运算符与魔法方法

python像大多数编程语言一样有那么多的运算符,为什么哪些运算符有着相应的功能呢?答案就在于运算符会触发相应的魔法方法。

python的运算符有算术运算符、逻辑运算符、比较运算符等:

算术运算符与魔法方法

  • +:数值相加,会调用相加对象的__add__或__radd__方法。
class Int(int):
def __add__(self, other):
print('diao yong le add')
return super().__add__(other) def __radd__(self, other):
print('diao yong le radd')
return super().__radd__(other)
if __name__ == "__main__":
a = Int(3)
b = Int(5)
c = a + b # 方法__add__方法被调用了
c = 3 + a # 方法__radd__方法被调用了,即py会优先调用自定义的对象的__add__和__radd__方法,如果没有才调用内置对象的相关方法。

我们可以通过重写相关的方法重新定义“+”符号的功能。

同理算术运算符的魔法方法:

a+b:数值相加,会调用对象的\__add\__或\__radd__方法。
a-b:数值相减,会调用对象的__rsub__或__sub__方法
a*b:数值相乘,调用__mul__和__rmul__方法
a/b:数值相除,调用__rtruediv__和__truediv__方法
a//b:整除,调用__floordiv__和__rfloordiv__方法。
a%b:求余,调用__mod__和__rmod__方法
a**b:求幂,调用__pow__和__rpow__方法;
-a:求负数,调用__neg__方法;
+a:调用__pos__方法

赋值运算符与魔法方法

a+=b:a与b相加赋值给a,调用__iadd__方法;
a-=b:a与b相减赋值给a,调用__isub__方法;
a*=b:a与b相乘赋值给a,调用__imul__方法;
a/=b:a与b相除赋值给a,调用__itruediv__方法;
a%=b:a与求余赋值给a,调用__imod__方法;
a//=b:a与b整除赋值给a,调用__ifloordiv__方法;
a**=b:a与b求幂赋值给a,调用__ipow__方法;
a&=b:a与b位与运算赋值给a,调用__iand__方法;
a|=b:a与b位或运算赋值给a,调用__ior__方法;
a^=b:a与b位异或运算赋值给a,调用__ixor__方法;

比较运算符与魔法方法

\>:大于,比较大小返回布尔值,调用比较参数的\__gt__方法
>=:大于等于,调用比较参数的\__ge__方法
<:小于,调用比较参数的\__lt__方法
<=:小于等于,调用比较参数的\__le__方法
==:等于,调用比较参数的__eq__方法
!=:不等于,调用比较参数的__ne__方法

位运算符与魔法方法

位运算符是将数字当做位来运算.

a = 10 # 位 a = 0000 1010
b = 15 # b = 0000 1111
c = a&b # c = 0000 1010
print(c) # 10

相应的魔法方法:

|:或,调用比较参数的__or__和__ror__方法
&:与,调用比较参数的__and__和__rand__方法
~:取反,调用比较参数的__invert__方法
<<:左移位运算,调用比较参数的__lshift__和__rlshift__方法
>>:右移动运算符,调用比较参数的__rrshift__和__rshift__方法
^:异或运算,调用比较参数的__rxor__和__xor__方法

参考

python进阶之关键字和运算符触发魔法方法的更多相关文章

  1. python进阶之内置函数和语法糖触发魔法方法

    前言 前面已经总结了关键字.运算符与魔法方法的对应关系,下面总结python内置函数对应的魔法方法. 魔法方法 数学计算 abs(args):返回绝对值,调用__abs__; round(args): ...

  2. python基础学习之类的继承、魔法方法

    什么是继承 即类A可以使用类B的方法,即B是A的父类,A是B的子类,AB之间是继承关系 class Father():  # 父类 def __init__(self,name,age): self. ...

  3. python类与对象各个算数运算魔法方法总结

    1.python类与对象各个算术运算魔法方法总结: 2.各个魔法方法应用举例: 3.实例训练: (1)我们都知道在 Python 中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常 ...

  4. Keil> 编译器特有的功能 > 关键字和运算符 > __weak

    __weak 此关键字指示编译器弱导出符号. 可以将 __weak 关键字应用于函数和变量声明以及函数定义. 用法 函数和变量声明 对于声明,此存储类指定一个 extern 对象声明,即使不存在,也不 ...

  5. Java学习笔记 01 基本数据类型、标识符、关键字和运算符

    一.基本数据类型 基本数据类型 数据类型 内存空间(8位等于1字节) 取值范围 备注 byte 8位 -128~127   short 16位 -32768~32767   int 32位 -2147 ...

  6. python学习笔记--变量和运算符

    一.变量命名规则 1.字母.数字.下划线组成 2.不以数字开头 3.关键字(也叫保留字),不能用作变量名 4.遵循PEP8命名规范 二.变量赋值 1.赋值符号 = 2.多重赋值 x=y=123 3.多 ...

  7. Python散列类型和运算符

    集合定义 集合的交 并 差 常见的运算符的用法 字典的定义 字典的 get  items  keys  pop  popitem  update  方法 三种逻辑运算 集合 集合特性 唯一性:不存在两 ...

  8. 编写Postgres扩展之二:类型和运算符

    原文:http://big-elephants.com/2015-10/writing-postgres-extensions-part-ii/ 编译:Tacey Wong 在上一篇关于编写Postg ...

  9. Python基础0:变量 赋值 表达式和运算符

    变量: 前面我们在使用print()输出内容的时候,如果内容很长,后面要再次输出的时候,就需重新在输入一遍. 如果给输出的内容起个简单的别名.这样我们用简短的别名来代替长内容,下次要输出的时候就直接使 ...

随机推荐

  1. Android性能测试工具APT

    APT源码地址:https://code.csdn.net/Tencent/apt APT,Android Performance Testing Tools,适用于开发自测和定位性能瓶颈,帮助测试人 ...

  2. 集成学习—boosting和bagging异同

    集成学习 集成学习通过构建并结合多个学习器来完成学习任务.只包含同种类型的个体学习器,这样的集成是“同质”的:包含不同类型的个体学习器,这样的集成是“异质”的.集成学习通过将多个学习器进行结合,常可获 ...

  3. SWERC2015-I Text Processor

    题意 给一个长度为\(n\)的字符串\(s\),再给定一个\(w\),问对于所有的\(i\in [1,n-w+1]\),\(s[i..i+w-1]\)有多少个不同字串.\(n,w\le 10^5\). ...

  4. 【JQuery】事件

    一.前言        接着上一章选择器的知识,继续啊jQuery的学习 二.内容 $(function(){}) 文档初始化加载 event.pageX 相对于文档左边缘的鼠标位置 event.pa ...

  5. 洛谷P1268 树的重量 【构造 + 枚举】

    题目描述 树可以用来表示物种之间的进化关系.一棵"进化树"是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异.现在,一个重要的问题是,根据物种之间的距离 ...

  6. 【学习笔记】ac自动机&fail树

    定义 解决文本串和多个模式串匹配的问题: 本质是由多个模式串形成的一个字典树,由tie的意义知道:trie上的每一个节点都是一个模式串的前缀: 在trie上加入fail边,一个节点fail边指向这个节 ...

  7. 【noip2018】【luogu5021】赛道修建

    题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,…,n1,2,…,n,有 n-1n−1 条适合于修建赛道的双向通 ...

  8. HDU4625 JZPTREE——第二类斯特林数

    复杂度大概O(nk) 一些尝试:1.对每个点推出1,2,3,,,到k次方的值.但是临项递推二项式展开也要考虑到具体每个点的dist 2.相邻k次方递推呢?递推还是不能避免k次方的展开 k次方比较讨厌, ...

  9. python基础----迭代器、生成器、协程函数及应用(面向过程实例)

    一.什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代 ...

  10. gdb打印STL和boost容器

    http://note.youdao.com/noteshare?id=b581e0db0084b6ba3011d9d27d372c91