python 常用的魔法方法
1. 构造方法
- __new__(cls,[...)
对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 __init__ 。
- __init__(self,[...])
使用传入的参数来初始化实例,不能返回除了None的任何值。
- __del__(self)
定义了当对象被垃圾回收时的行为。 当对象需要在销毁时做一些处理的时候这个方法很有用,比如 socket 对象、文件对象。但是需要注意的是,当Python解释器退出但对象仍然存活的时候, __del__ 并不会执行。
2. 可调用的对象
- __call__(self, [args...])
允许类的一个实例像函数那样被调用。
class XClass:
def __call__(self, a, b):
return a + b
def add(a, b):
return a + b
x = XClass()
print('x(1, 2)', x(1, 2)) #3
print('callable(x)', callable(x)) # True
print('add(1, 2)', add(1, 2)) #3
print('callable(add)', callable(add)) # True
3. 属性访问控制
- __getattr__(self, name)
定义了你试图访问一个不存在的属性时的行为。因此,重载该方法可以实现捕获错误拼写然后进行重定向, 或者对一些废弃的属性进行警告。
- __setattr__(self, name, value)
可以用于真正意义上的封装。它允许你自定义某个属性的赋值行为,不管这个属性存在与否。需要注意避免"无限递归"的错误
def__setattr__(self, name, value):
self.name = value
# 每一次属性赋值时, __setattr__都会被调用,因此不断调用自身导致无限递归了。
因此正确的写法应该是:
def__setattr__(self, name, value):
self.__dict__[name] = value
- __delattr__(self, name)
用于处理删除属性时的行为。同样要避免"无限递归"的错误。
4. 类的标识
- __str__(self)
定义对类的实例调用 str() 时的行为。
- __repr__(self)
实例使用repr()时调用。str()和repr()都是返回一个代表该实例的字符串,
主要区别在于: str()的返回值要方便人来看,而repr()的返回值要方便计算机看。
- __format__(self)
定义当类的实例用于新式字符串格式化时的行为,例如, “Hello, 0:abc!”.format(a) 会导致调用 a.__format__(“abc”) 。
- __hash__(self)
它必须返回一个整数,其结果会被用于字典中键的快速比较。同时注意一点,实现这个魔法方法通常也需要实现 __eq__ ,并且遵守: a == b 意味着 hash(a) == hash(b)。
5. 操作符
- 比较操作符:__cmp__(self, other), __eq__(self, other), __ne__(self, other)等
- 数值操作符:__pos__(self), __neg__(self) __abs__(self), __round__(self, n)等
- 算数操作符: __add__(self), __sub__(self), __mul__(self), __mod__(self), __and__(self)等
- 类型转换操作符: __int__(self),__complex__(self),__index__(self) 等
6. 自定义序列
可以让你的Python类表现得像是内建序列类型(字典,元组,列表,字符串等)
- __len__(self)
返回容器的长度,可变和不可变类型都需要实现。
- __getitem__(self, key)
定义对容器中某一项使用 self[key] 的方式进行读取操作时的行为。也是可变和不可变容器类型都需要实现。它应该在键的类型错误式产生 TypeError 异常,同时在没有与键值相匹配的内容时产生 KeyError 异常。
- __setitem__(self, key)
定义对容器中某一项使用 self[key] 的方式进行赋值操作时的行为。它是可变容器类型必须实现的一个方法,同样应该在合适的时候产生 KeyError 和 TypeError 异常。
- __iter__(self, key)
它应该返回当前容器的一个迭代器。迭代器以一连串内容的形式返回,最常见的是使用 iter() 函数调用,以及在类似 for x in container: 的循环中被调用。迭代器是他们自己的对象,需要定义 iter 方法并在其中返回自己。
- __reversed__(self)
义了对容器使用 reversed() 内建函数时的行为。它应该返回一个反转之后的序列。
- __contains__(self, item)
定义了使用 in 和 not in 进行成员测试时类的行为。如果没有定义,那么Python会迭代容器中的元素来一个一个比较,从而决定返回True或者False。
- __missing__(self ,key)
在字典的子类中使用,它定义了当试图访问一个字典中不存在的键时的行为
7. 拷贝
- __copy__(self)
定义对类的实例使用 copy.copy() 时的行为。 返回一个对象的浅拷贝
- __deepcopy__(self, memodict={})
对实例使用copy.deepcopy()时调用。返回一个对象的深拷贝