「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」
前言
在Python语言中,一切皆为对象,因此Python是支持面向对象的高级编程语言。在Python面向对象编程特性 一文中,Python语言是支持封装、继承、多态三个特性的。
- 封装:使用黑盒的方式将对象信息隐藏在内部,外部无法进行访问
- 继承:子父类概念,将父类称为基类,子类可以继承所有父类的特性,极大地提高代码的复用性
- 多态:指向同一个方法,不同对象产生行为是不同的。继承和方法重写是多态的两个前提
在创建类的时候,我们总会调用系统以"__"双下换线开头结尾的方法,来对对象进行创建、初始化、销毁等操作,如以下栗子:
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
def __del__(self):
print("系统销毁对象{0}".format(self))
在上述栗子中,我们都知道__init__()是构造方法、__del__()是析构方法,__new__()创建实例对象,除此之外它们还有一个统一的名称叫做魔法方法。
本期,我们将学习Python中拥有一个很帅气的名称魔法方法,Let's go~~
1. 魔法方法概述
-
什么叫魔法方法?
在Python中,定义以"__"双下划线开头结尾的方法,行内内部大家都统称为“magic method”。
比如我们常见的构造方法、析构方法都是属于魔法方法中。
在Python官方文档中,魔法方法分布比较分散,并且介绍时也无案例说明,通常晦涩难懂。
-
魔法方法的特点
- 魔法方法主要定义类对象的方法,无法直接调用
- 默认情况,Python解释器会自动调用。特殊情况,可重写该方法。
- 魔法方法可用于对象初始化、控制属性访问、创建自定义等操作
- 魔法方法包提供包含如比较、数值计算、单双目运算、类型转换等方法
2. 构造销毁方法
我们上述创建一个Student类,定义一个实例化类StudentA,看看Python解释器内部会分别调用三个魔法方法。
-
__new__():是对象实例化时,首先会调用该方法,创建实例,并把类参数name,age传给__init__()。如果__new__()未返回一个类实例,则__init__()方法将不执行。 -
__init__():在__new__()创建实例后,对实例化参数进行初始化赋值。因为,对象是由__new__()创建和__init__()定制,共同构建完成的,__init__()返回值为None,否则在运行时会引发TypeError. -
__del__():在实例对象比销毁时被调用。对象被垃圾回收时才会调用该方法,需要注意的是Python解释器退出时,但对象仍然存活的时候,__del__()不会被执行的。如在程序中需要销毁对象,建议尽量手工调用del()方法进行清理。
3. 属性访问方法
Python 魔法方法提供控制属性访问的方法。
-
__getattr__(self,name): 该方法用于访问对象不存在的属性时,会调用定义访问行为。这个方法适合于普通的拼写错误的获取和重定向,对获取不建议的属性时会给出警告或者处理一个AttributteError。 -
__setattr__(self,name,value): 是封装属性,无论属性是否存在,都允许定义对属性的赋值行为,可以对属性的值进行个性化定义。在使用__setattr__(self,name,value)时,需要避免无限递归的错误。 -
__delattr__():与__setattr__(self,name,value)类似,但是不对属性进行赋值而是进行删除。该方法仅在del obj.name 对于对象有意义时才被实现。同样在实现时,需要避免无限循环的错误。
4. 上下文管理器
Python中对文件打开、关闭操作。提供了with 语句,其实质就是运行上下文管理器,由三部分组成。
- 上下文管理协议
- 上下文管理器
- 上下文运行时
以上三部分,其中上下文管理协议是由 __enter__() 和 __exit__() 两个方法相互协作完成的。
-
__enter__():进入运行时上下文并返回此对象关联到该运行时上下文的其他对象上。__enter__()该方法的返回值会绑定到使用上下文管理器with语句的as 子句中的标识符。 -
__exit__(): 退出运行时上下文并返回一个bool标识的异常是否应当被屏蔽。当with语句体重发生异常,则参数会包含异常类型、值和回溯信息,否则三个参数都是None。
5. 其他方法
- 比较操作符魔法方法:
| 方法 | 说明 |
|---|---|
__cmp__(self,other) | 比较方法里最基本的魔法方法 |
__eq__(self,other) | 定义相等符号,== |
__ne__(self,other) | 定义不等于符号,!= |
__lt__(self,other) | 定义小于符号,< |
__gt__(self,other) | 定义大于符号,> |
__le__(self,other) | 定义小于等于符号,<= |
__ge__(self,other) | 定义大于等于符号,>= |
____(self) | |
____(self) |
- 单目操作符魔法方法:
| 方法 | 说明 |
|---|---|
__pos__(self) | 实现取正操作 |
__neg__(self) | 实现取负操作 |
__adbs__(self) | 实现绝对值操作 |
__invert__(self) | 实现取反操作 |
__round__(self,n) | 实现内建函数 |
__floor__(self) | 实现向下取整 |
__ceil__(self) | 实现向上取整 |
__trunc__(self) | 实现距离零最近的的整数 |
- 双目运算魔法方法
| 方法 | 说明 |
|---|---|
__add__(self,other) | 实现加法运算 |
__sub__(self,other) | 实现减法运算 |
__mul__(self,other) | 实现乘法运算 |
__floordiv__(self,other) | 实现"//"操作符整除运算 |
__div__(self,other) | 实现"/"操作符除法操作 |
__truediv__(self,other) | 实现真实除法 |
__mod__(self,other) | 实现"%"操作符代表的取模运算 |
__divmod__(self,other) | 实现一个内建函数divmod() |
__pow__(self,other) | 实现一个指数操作 |
__lshift__(self,other) | 实现一个位左移操作 |
__rshift__(self,other) | 实现一个位右移操作 |
__and__(self,other) | 实现一个按位进行与操作 |
__or__(self,other) | 实现一个按位进行或操作 |
__xor__(self,other) | 实现一个按位异或操作 |
- 增量运算魔术方法
| 方法 | 说明 |
|---|---|
__iadd__(self,other) | 实现加法赋值 |
__isub__(self,other) | 实现减法赋值 |
__imul__(self,other) | 实现乘法赋值 |
__ifloordiv__(self,other) | 实现"//"=操作符整除赋值 相当于//= |
__idiv__(self,other) | 实现"/"操作符除法赋值 /= |
__itruediv__(self,other) | 实现真实除法赋值 |
__imod__(self,other) | 实现"%"操作符代表的取模赋值 %= |
__ipow__(self,other) | 实现一个指数赋值 **= |
__ilshift__(self,other) | 实现一个位左移赋值 <<= |
__irshift__(self,other) | 实现一个位右移赋值 >>= |
__iand__(self,other) | 实现一个按位进行与赋值 &= |
__ior__(self,other) | 实现一个按位进行或赋值 |
__ixor__(self,other) | 实现一个按位异或赋值 ^= |
- 类型转换魔术方法
| 方法 | 说明 |
|---|---|
__int__(self) | 转换成整型 |
__long__(self) | 转换成长整型 |
__float__(self) | 转换成浮点型 |
__complex__(self) | 转换成复数型 |
__hex__(self) | 转换十六进制 |
__oct__(self) | 转换八进制 |
__trunc__(self) | 整型截取 |
__index__(self) | 执行切片操作数值型 |
__coerce__(self) | 执行混合类型运算 |
总结
本期,主要对Python 魔法方法进行详细的学习。在日常工作,我们可以使用Python 魔法方法方便我们快速进行面向对象编程。
以上是本期内容,欢迎大佬们点赞评论,下期见~