Python--25 魔法方法:构造和析构 魔法方法总结
魔法方法总是被双下划线包围,例如__init__
魔法方法是面向对象的Python的一切,如果你不知道魔法方法,说明你还没有意识到面向对象Python的强大
魔法方法的‘魔力’体现在他们总能够在适当的时候被调用
1.__init__(self[,...]) 返回一个None对象
类在实例化的时候默认会调用的函数
>>> class Rectangle: ... def __init__(self,x,y): ... self.x = x ... self.y = y ... def getPeri(self): ... return (self.x + self.y) * 2 ... def getArea(self): ... return self.x * self.y ... >>> rect = Rectangle(3,4) >>> rect.getPeri() 14 >>> rect.getArea() 12
2.__new__(cls[,...])对象实例化第一次调用的方法,返回类的实例对象
继承一个不可变类型的时候,又需要进行修改的时候,那么这个特性就特别重要
>>> class CapStr(str): ... def __new__(cls,string): ... string = string.upper() ... return str.__new__(cls,string) ... >>> a = CapStr('I love you') >>> a 'I LOVE YOU'
3.__del__(self) 析构器
垃圾回收机制,当这个数据没有任何变量与之相关联的时候
>>> class C: ... def __init__(self): ... print('我是init方法,我被执行了') ... def __new__(self): ... print('我是new方法,我被执行了') ... def __del__(self): ... print('我是__del__方法,我被执行了') ... >>> >>> class C: ... def __init__(self): ... print('我是__init__方法,我被执行了') ... def __del__(self): ... print('我是__del__方法,我被执行了') ... >>> c1 = C() 我是__init__方法,我被执行了 >>> c2 = c1 >>> c3 = c1 >>> del c3 >>> del c2 >>> del c1 我是__del__方法,我被执行了
算术运算
Python将两个int对象进行向相加的操作
Python的魔法方法还提供了自定义数值的处理,通过对魔法方法的重写 ,进行对象间的算术运算
>>> type(len) <class 'builtin_function_or_method'> >>> type(dir) <class 'builtin_function_or_method'> >>> type(int) <class 'type'> >>> type(list) <class 'type'> >>> class C: ... pass ... >>> type(C) <class 'type'> >>> a = int('123') >>> b = int('456') >>> a + b 579
算术运算1
方法名 | 方法说明 |
__add__(self,other) | 定义加法的行为:+ |
__sub__(self,other) | 定义减法的行为:_ |
__mul__(self,other) | 定义乘法的行为:* |
__truediv__(self,other) | 定义真驻法的行为:/ |
__floordiv__(self,other) | 定义整数除法的行为:// |
__mod__(self,other) | 定义取模算法的行为:% |
__divmod__(self,other) | 定义当被divmod()调用时的行为 |
__pow__(self,other[,modulo]) | 定义当被Power()调用时或**运算时的行为 |
__lshift__(self,other) | 定义按位左移位的行为:<< |
__rshift__(self,other) | 定义按位右移位的行为:>> |
__and__(self,other) | 定义按位与操作的行为:& |
__xor__(self,other) | 定义安慰异或操作的行为:^ |
__or__(self,other) | 定义按位或操作的行为:| |
>>> class New_int(int): ... def __add__(self,other): ... return int.__sub__(self,other) ... def __sub__(self,other): ... return int.__add__(self,other) ... >>> a = New_int(3) >>> b = New_int(5) >>> a + b -2 >>> a - b 8
注意:
>>> class Try_int(int): ... def __add__(self, other): ... return self + other ... def __sub__(self, other): ... return self + other ... >>> a = Try_int(3) >>> b = Try_int(5) >>> a + b Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in __add__ File "<stdin>", line 3, in __add__ File "<stdin>", line 3, in __add__ [Previous line repeated 329 more times] RecursionError: maximum recursion depth exceeded while calling a Python object
WHY?
a + b -> return self + other = a + b
修改:
>>> class Try_int(int): ... def __add__(self, other): ... return int(a) + int(b) ... >>> a =Try_int(3) >>> b = Try_int(5) >>> a + b 8
>>> a = divmod(5,3) >>> a (1, 2)
算术运算2
>>> class int(int): ... def __add__(self, other): ... return int.__sub__(self,other) ... >>> a = int('5') >>> a 5 >>> b = int('3') >>> b = int('3') >>> a + b 2
魔法方法 | 含义 |
基本的魔法方法 | |
__new__(cls[, ...]) |
1.__new__是在一个对象实例化的时候所调用的第一个方法 2.它的第一个参数是这个类,其他参数是用来直接传递给__init__方法 3. __new__ 决定是否要使用 该 __init__ 方法,因 为 __new__ 可以 调 用其他 类 的构造 |
__init__(self[, ...]) | 构造器,当一个 实 例被 创 建的 时 候 调 用的初始化方法 |
__del__(self) | 析构器,当一个 实 例被 销 毁的 时 候 调 用的方法 |
__call__(self[, args...]) | 允 许 一个 类 的 实 例像函数一 样 被 调 用:x(a, b) 调 用 x.__call__(a, b) |
__len__(self) | 定义当被 len() 调 用 时 的行 为 |
__repr__(self) | 定义当被 repr() 调 用 时 的行 为 |
__str__(self) | 定义当被 str() 调 用 时 的行 为 |
__bytes__(self) | 定义当被 bytes() 调 用 时 的行 为 |
__hash__(self) | 定义当被hash()调用的行为 |
__bool__(self) | 定义当被 bool() 调 用 时 的行 为,应该 返回 True 或 False |
__format__(self, format_spec) | 定义当被 format() 调 用 时 的行 为 |
有 关 属性 | |
__getattr__(self, name) | 定义当用 戶试图获 取一个不存在的属性 时 的行 为 |
__getattribute__(self, name) | 定义当 该类 的属性被 访问时 的行 为 |
__setattr__(self, name, value) | 定义当一个属性被 设 置 时 的行 为 |
__delattr__(self, name) | 定义当一个属性被 删 除 时 的行 为 |
__dir__(self) | 定义当 dir() 被 调 用 时 的行 为 |
__get__(self, instance, owner) | 定义当描述符的 值 被取得 时 的行 为 |
__set__(self, instance, value) | 定义当描述符的 值 被改 变时 的行 为 |
__delete__(self, instance) | 定义当描述符的 值 被 删 除 时 的行 为 |
比 较 操作符 | |
__lt__(self, other) | 定义小于号的行 为: x < y 调 用 x.__lt__(y) |
__le__(self, other) | 定义小于等于号的行 为: x <= y 调 用 x.__le__(y) |
__eq__(self, other) | 定义等于号的行 为: x == y 调 用 x.__eq__(y) |
__ne__(self, other) | 定义不等号的行 为: x != y 调 用 x.__ne__(y) |
__gt__(self, other) | 定义大于号的行 为: x > y 调 用 x.__gt__(y) |
__ge__(self, other) | 定义大于等于号的行 为: x >= y 调 用 x.__ge__(y) |
算数运算符 | |
__add__(self, other) | 定义加法的行为: + |
__sub__(self, other) | 定义减法的行为: - |
__mul__(self, other) | 定义乘法的行 为: * |
__truediv__(self, other) | 定义真除法的行 为: / |
__floordiv__(self, other) | 定义整数除法的行 为: // |
__mod__(self, other) | 定义取模算法的行 为: % |
__divmod__(self, other) | 定义当被 divmod() 调 用 时 的行 为 |
__pow__(self, other[, modulo]) | 定义当被 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) | (与上方相同,当左操作数不支持相 应 的操作 时 被 调 用) |
__rdivmod__(self, other) | (与上方相同,当左操作数不支持相 应 的操作 时 被 调 用) |
__rpow__(self, other) | (与上方相同,当左操作数不支持相 应 的操作 时 被 调 用) |
__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) | 定义 赋值 按位或操作的行 为: |= |
一元操作符 | |
__pos__(self) | 定义 正 号的行 为: +x |
__neg__(self) | 定义 负 号的行 为: -x |
__abs__(self) | 定义当被 abs() 调 用 时 的行 为 |
__invert__(self) | 定义按位求反的行 为: ~x |
类 型 转换 | |
__complex__(self) |
定义当被complex()调用 时 的行 为( 需要返回恰当的 值) |
__int__(self) | 定义当被 int() 调 用 时 的行 为( 需要返回恰当的 值) |
__float__(self) | 定义当被 float() 调 用 时 的行 为( 需要返回恰当的 值) |
__round__(self[, n]) | 定义当被 round() 调 用 时 的行 为( 需要返回恰当的 值) |
__index__(self) |
1. 当 对 象是被 应 用在切片表达式中 时,实现 整形强制 转换 |
上下文管理(with 语 句) | |
__enter__(self) |
1. 定义当使用 with 语 句 时 的初始化行 为 |
__exit__(self, exc_type, exc_value,traceback) |
1. 定义当一个代 码块 被 执 行或者 终 止后上下文管理器 应该 做什么 |
容器 类 型 | |
__len__(self) | 定义当被 len() 调 用 时 的行 为( 返回容器中元素的个数) |
__getitem__(self, key) | 定义 获 取容器中指定元素的行 为, 相当于 self[key] |
__setitem__(self, key, value) | 定义 设 置容器中指定元素的行 为, 相当于 self[key] = value |
__delitem__(self, key) | 定义 删 除容器中指定元素的行 为, 相当于 del self[key] |
__iter__(self) | 定义当迭代容器中的元素的行 为 |
__reversed__(self) | 定义当被 reversed() 调 用 时 的行 为 |
__contains__(self, item) | 定义当使用成 员测试 运算符(in 或 not in )时 的行 为 |
a + b
当 a 加法不支持的时候,python会自动选择b的加法 即加法反运算
>>> class Rint(int): ... def __radd__(self,other): ... return int.__sub__(self,other) ... >>> a = Rint(4) >>> b = Rint(2) >>> a + b 6 >>> 1 + b 1
注意: self,other位置
>>> class Rint(int): ... def __rsub__(self,other): ... return int.__sub__(other,self) ... >>> a = Rint(5) >>> 3 - a -2