魔法方法
概念
- 魔法方法总是被双下划线包裹, 例如__init__()
- 魔法方法会在恰当的时候自动调用
- 魔法方法的第一个参数为cls(类方法)或者self(实例方法)
基本魔法方法
- __init__(self, []): 构造器方法, 当一个实例对象被创建的时候自动调用
- __new__(cls,[]): 在一个对象实例化时调用的方法, 在调用__init__()前, 先调用__new__()
- __new__()至少需要一个cls参数, 代表要实例化的类, 此参数有python解释器自动提供, 后面的参数直接传递给__init__()
- __new__()对当前类进行了实例化,并将实例返回,传给__init__()的self。但是,执行了__new__(),并不一定会进入__init__(),只有__new__()返回了,当前类cls的实例,当前类的__init__()才会进入。
- 若__new__()没有正确的返回当前类的cls, 那么__init__()是不会被调用的
- __new__方法主要是当你继承一些不可变的 class 时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径
- __del__(self, []): 析构器方法, 当一个对象被析构时, 自动调用
- __str__(self): 返回对象的字符串表示形式, 当一个对象被转为字符串时, 自动调用, 可以用来增强返回结果的可读性
- __repr__(self): 调试所用
算术运算符
- __add__(self, other): 相当于+重载方法
- __sub__(self, other): 相当于-重载方法
- __mul__(self, other): 相当于*重载方法
- __truediv__(self, other): /
- __floordiv__(self, other): //
- __mod__(self, other): %
- __divmod__(self, other): 定义当被divmod()调用时的行为
- divmod(a, b): 把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。
- __pow__(self, other[, module]): 当被power()或**调用时的行为
- __lshift__(self, other): <<
- __rshift__(self, other): >>
- __and__(self, other): &
- __xor__(self, other): ^
- __or__(self, other): |
反算术运算符
- __radd__(self, other)定义加法的行为:+
- __rsub__(self, other)定义减法的行为:-
- __rmul__(self, other)定义乘法的行为:*
- __rtruediv__(self, other)定义真除法的行为:/
- __rfloordiv__(self, other)定义整数除法的行为://
- __rmod__(self, other) 定义取模算法的行为:%
- __rdivmo__d__(self, other)定义当被 divmod() 调用时的行为
- __rpow__(self, other[, module])定义当被 power() 调用或 ** 运算时的行为
- __rlshift__(self, other)定义按位左移位的行为:<<
- __rrshift__(self, other)定义按位右移位的行为:>>
- __rand__(self, other)定义按位与操作的行为:&
- __rxor__(self, other)定义按位异或操作的行为:^
- __ror__(self, other)定义按位或操作的行为:|
增量赋值运算符
- __iadd__(self, other)定义赋值加法的行为:+=
- __isub__(self, other)定义赋值减法的行为:-=
- __imul__(self, other)定义赋值乘法的行为:*=
- __itruediv__(self, other)定义赋值真除法的行为:/=
- __ifloordiv__(self, other)定义赋值整数除法的行为://=
- __imod__(self, other)定义赋值取模算法的行为:%=
- __ipow__(self, other[, modulo])定义赋值幂运算的行为:**=
- __ilshift__(self, other)定义赋值按位左移位的行为:<<=
- __irshift__(self, other)定义赋值按位右移位的行为:>>=
- __iand__(self, other)定义赋值按位与操作的行为:&=
- __ixor__(self, other)定义赋值按位异或操作的行为:^=
- __ior__(self, other)定义赋值按位或操作的行为:|=
一元运算符
- __neg__(self)定义正号的行为:+x
- __pos__(self)定义负号的行为:-x
- __abs__(self)定义当被abs()调用时的行为
- __invert__(self)定义按位求反的行为:~x
属性访问
- __getattr__(self, name): 定义当用户试图获取一个不存在的属性时的行为。
- __getattribute__(self, name):定义当该类的属性被访问时的行为(先调用该方法,查看是否存在该属性,若不存在,接着去调用__getattr__)。
- __setattr__(self, name, value):定义当一个属性被设置时的行为。
- __delattr__(self, name):定义当一个属性被删除时的行为。
描述符
- __get__(self, instance, owner)用于访问属性,它返回属性的值。
- __set__(self, instance, value)将在属性分配操作中调用,不返回任何内容。
- __del__(self, instance)控制删除操作,不返回任何内容。
定制序列
- 不可变序列
- __len__()
- __getitem__()
- 实现这两个魔法方法即可将对象定制为不可变序列
- 可变序列
- __len__()
- __getitem__()
- __setitem__()
- __setitem__()
- 实现这四个魔法方法即可将对象丁志伟可变序列
迭代器
- 迭代器可以将对象可迭代化
- 迭代器有两个基本方法: iter()和next()
- iter(object)用于生成迭代器
- next(iterator[, default])返回迭代器的下一个项目
- iterator – 可迭代对象
- default – 可选, 用于设置在没有下一个元素时返回该默认值,如果不设置,又没有下一个元素则会触发 StopIteration 异常。
把一个类作为一个迭代器使用需要在类中实现两个魔法方法 __iter__() 与 __next__() 。 - __iter__(self)定义当迭代容器中的元素的行为,返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
- __next__() 返回下一个迭代器对象。
- StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
生成器
- 使用了yield的函数被称为生成器
- 生成器类似迭代器
- 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行
练习题
import time
class Timer:
def __init__(self):
self.startTime = 0
self.time = 0
def start(self):
self.startTime = time.time()
def stop(self):
if self.startTime == 0:
return "未计时"
else:
self.time = time.time() - self.startTime
self.startTime = 0
return self.time
def __str__(self):
return time.time() - self.startTime
def __add__(self, other):
return time.time() - self.startTime + time.time() - other.startTime
def __radd__(self, other):
return time.time() - self.startTime + time.time() - other.startTime
timer = Timer()
timer2 = Timer()
print(timer.stop())
timer.start()
timer2.start()
for x in range(100000000):
pass
print(timer + timer2)