Python中存在大量的特殊方法,官方一般称之为魔法方法(magic method),也叫双下方法(dunder method).其方法形式为以双下划线为起始,并且以双下划线为结束,
__funcName__ . 魔法方法是指Python内部已经包含的,被双下划线所包围的方法,这些方法在进行特定的操作时会自动被调用,它们是Python面向对象下智慧的结晶。
流畅的Python , 知乎专栏 , 方法指南 ,某教程
日常使用例子
- 在日常使用中我们其实经常调用,最常见的便是 __init__ 方法,在创建实例的过程中会自动调用,进行初始化。
- len(),方法会自动调用我们的__len__ 方法等等。
调用形式多样,没必要意义列举。魔法方法的出现使得Python展现了强大的自由度,简化了繁琐的重写轮子的步骤;
调用方法列举
Python中每个魔法函数都对应了一个Python内置函数或操作,比如__str__对应str函数,__lt__对应小于号<等。Python中的魔法函数可以大概分为以下几类:
类的构造与删除
1 2 3
| object.__new__(self, ...) object.__init__(self, ...) object.__del__(self)
|
二元操作
1 2 3 4 5 6 7 8 9 10 11 12
| + object.__add__(self, other) - object.__sub__(self, other) * object.__mul__(self, other) // object.__floordiv__(self, other) / object.__div__(self, other) % object.__mod__(self, other) ** object.__pow__(self, other[, modulo]) << object.__lshift__(self, other) >> object.__rshift__(self, other) & object.__and__(self, other) ^ object.__xor__(self, other) | object.__or__(self, other)
|
扩展二元操作**
1 2 3 4 5 6 7 8 9 10 11 12
| += object.__iadd__(self, other) -= object.__isub__(self, other) *= object.__imul__(self, other) /= object.__idiv__(self, other) //= object.__ifloordiv__(self, other) %= object.__imod__(self, other) **= object.__ipow__(self, other[, modulo]) <<= object.__ilshift__(self, other) >>= object.__irshift__(self, other) &= object.__iand__(self, other) ^= object.__ixor__(self, other) |= object.__ior__(self, other)
|
一元操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| - object.__neg__(self) + object.__pos__(self) abs() object.__abs__(self) ~ object.__invert__(self) complex() object.__complex__(self) int() object.__int__(self) long() object.__long__(self) float() object.__float__(self) oct() object.__oct__(self) hex() object.__hex__(self) round() object.__round__(self, n) floor() object__floor__(self) ceil() object.__ceil__(self) trunc() object.__trunc__(self)
|
比较函数
1 2 3 4 5 6
| < object.__lt__(self, other) <= object.__le__(self, other) == object.__eq__(self, other) != object.__ne__(self, other) >= object.__ge__(self, other) > object.__gt__(self, other)
|
类的表示与输出
1 2 3 4 5 6 7
| str() object.__str__(self) repr() object.__repr__(self) len() object.__len__(self) hash() object.__hash__(self) bool() object.__nonzero__(self) dir() object.__dir__(self) sys.getsizeof() object.__sizeof__(self)
|
类容器**
1 2 3 4 5 6 7 8
| len() object.__len__(self) self[key] object.__getitem__(self, key) self[key] = value object.__setitem__(self, key, value) del[key] object.__delitem__(self, key) iter() object.__iter__(self) reversed() object.__reversed__(self) in操作 object.__contains__(self, item) 字典key不存在时 object.__missing__(self, key)
|
相关应用
通过上面的描述我们已经知道我们常见的一些操作,其实是调用了魔法方法的缘故,但是知道又有什么意义呢?
意义:通过重写上述魔法方法,可以构造符合Python风格的类。这里的Python风格就是自己构造的类也可以使用Python常见的特性,比如你构建了集合类,可以使用切片、索引、迭代等等特性,你构建了向量类,可以利用操作符” +,-,*,/ ” , 实现向量的加减乘除。
向量类构造实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| from math import hypot
class Vector:
def __init__(self, x=0, y=0): self.x = x self.y = y
def __repr__(self): return 'Vector(%r, %r)' % (self.x, self.y)
def __abs__(self): return hypot(self.x, self.y)
def __bool__(self): return bool(abs(self))
def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y)
def __mul__(self, scalar): return Vector(self.x * scalar, self.y * scalar) v1 = Vector(2,1) v2 = Vector(3,4) print(v1 + v2) print(abs(v2)) print(v1 * 3)
|
通过实现类内部的魔法方法,使得自定义的类也能够使用Python运算符进行相关计算,符合Python风格。当然你也可以像其他方法那样,实现相关功能,只是没有了Python风格。