**Python中的魔法方法(Magic Methods)是用双下划线(例如__init__)实现的特殊方法,它们允许您自定义类的行为,构建更加强大的自定义对象,使类能够与Python内置函数和操作符进行交互。
- 初始化方法:init
- 构造方法:new
- 使对象可迭代:通过实现 iter 和 next 魔法方法,您可以使对象成为可迭代的,并能够使用for循环遍历它。
- 支持上下文管理器:通过实现 enter 和 exit 魔法方法,您可以使对象成为上下文管理器,从而支持with语句,以确保资源的正确分配和释放。
- 运算符相关: 实现对象的加减乘除等,add,__mul__等
- 比较对象:通过实现 eq、lt、le 等魔法方法,您可以定义对象之间的比较操作,以便根据您的需求进行自定义比较。
- 属性访问控制:通过实现 getattribute 和 setattr 魔法方法,您可以自定义对象属性的访问和设置行为,从而实现更高级的属性控制。
- 资源管理:使用 del 魔法方法,您可以在对象被销毁之前执行清理操作,例如关闭文件或释放资源。
- 序列化:通过实现 getstate 和 setstate 方法,您可以定义对象的序列化和反序列化行为,以便将对象保存到文件或数据库中。
总之,魔法方法使您能够更好地控制和自定义类的行为,使其适应您的特定需求。它们是Python中强大的工具,用于创建更灵活和强大的自定义类。本期,我们详细几个常用的魔法方法。**
(1)__init__方法
初始化魔法方法,用以实例化一个对象,它在类对象创建后被自动触发,为对象添加对象的所属成员或分配初始值,执行与对象相关的初始化操作。不需要显示返回任何内容,它的第一个参数是对象实例本身。
class Person(object):
#初始化人类方法,分配对象初始值
def __init__(self,name,age):
self.name = name
self._age = age
def __repr__(self):
return "name = %s and age = %s"%(self.name,self._age)
tom = Person("Tom","23")
print(tom)
(2)__new__方法
构造方法魔法方法,为对象分配内存空间,管理控制对象的生成过程。重载object基类的__new__方法。一个cls接受当前类,其它参数依据实例化的参数决定。返回值:可有可无,若没有返回值则实例化结果为None。
class Person(object):
# 构造方法
def __new__(cls,sex):
print(cls)
if sex == "男":
return object.__new__(cls)
# 也可以
# return object.__new__(Person)
else:
return None
tom = Person("男")
jac = Person("女")
print(tom)
print(jac)
既然__new__方法可以管理对象的生成过程,自然有一个非常经典的应用:单例模式。python单例模式是一种常见的设计模式,它的主要目的是确保一个类只能产生一个实例,即某个实例在项目的整个生命周期中只能存在一个或指向同一个内存空间,并提供一个全局访问点来获取该实例。关于单例模式的应用,我们后期详解。
import threading
class Singleton(object):
#多线程安全,加锁
lock_ = threading.Lock()
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"):
with Singleton.lock_:
if not hasattr(Singleton, "_instance"):
Singleton._instance = object.__new__(cls)
return Singleton._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1)
print(obj2)
print(obj1 is obj2)
(3)__del__魔法方法
析构方法,对象被系统回收时自动触发(del不一定触发),回收程序使用过程中的信息变量等。在 del 方法中,您可以执行资源清理的操作,例如关闭文件、释放网络连接、清除缓存或执行其他与对象的生命周期相关的清理工作。但要小心使用它,因为它可能会导致一些问题,特别是在多线程或异步编程中。
class MyClass:
def __init__(self):
self.resource = None
def initialize_resource(self):
self.resource = open('sample.csv', 'r')
print(self.resource.readlines())
def close_resource(self):
if self.resource:
self.resource.close()
def __del__(self):
# 在对象销毁时执行清理操作
self.close_resource()
# 创建对象
obj = MyClass()
obj.initialize_resource()
print(obj)
# 对象被销毁时,__del__ 方法会被自动调用
# del obj
(4)repr()方法与__str__()方法
在Python中,repr() 和 str() 是两个用于定制对象字符串表示的特殊魔法方法。它们用于不同的目的,并且在不同的情况下被调用。
repr() 方法:返回一个包含对象可用于重建的字符串表示。一般情况下,repr() 方法用于开发者,它的目的是提供对象的详细信息,以便调试和开发。如果没有定义__str__()方法,print()函数会调用__repr__()方法以获取字符串表示。
str() 方法:返回一个用户友好的字符串表示,通常用于将对象的信息展示给终端用户。
如果定义了__str__()方法,当使用str()函数或print()函数打印对象时,会调用__str__()方法以获取字符串表示。如果没有定义__str__()方法,Python将查找__repr__()方法。
class MyClass:
def __init__(self, value):
self.value = value
def __str__(self):
return f"Value: {self.value}"
def __repr__(self):
return f"MyClass({self.value})"
demo = MyClass(27)
print(demo)
demo
(5)数值运算相关魔法方法
Python中的运算相关魔法方法(Magic Methods)用于定义对象的运算行为,例如加法、减法、比较等。这些方法允许您自定义类的对象与内置数据类型之间的交互方式。以下是一些常用的运算相关魔法方法:
add(self, other):定义对象的加法操作。
sub(self, other):定义对象的减法操作。
mul(self, other):定义对象的乘法操作。
truediv(self, other):定义对象的除法操作。
floordiv(self, other):定义对象的整数除法操作。
mod(self, other):定义对象的取模操作。
pow(self, other, modulo=None):定义对象的指数操作。
这些方法允许您自定义类的对象与内置数据类型(如整数、浮点数)之间的运算行为。例如,如果您定义了__add__方法,您可以使用 + 运算符来执行自定义的加法操作。
import math
class MyVector(object):
def __init__(self,vertor):
self._values = list(vertor)
def __repr__(self):
return f"MyVector({self._values})"
def __str__(self):
return f"Value: {self._values}"
def __len__(self):
return len(self._values)
def __add__(self,another):
assert len(self) == len(another),"向量维度不相等"
return MyVector([a+b for a,b in zip(self._values,another._values)])
def __sub__(self,another):
assert len(self) == len(another),"向量维度不相等"
return MyVector([a+b for a,b in zip(self._values,another._values)])
def __mul__(self,k):
"""返回数量乘法的结果向量:self*k"""
return MyVector([k*e for e in self._values])
def __rmul__(self,k):
"""返回数量乘法的结果向量:k*self"""
"""如果左侧对象的 __mul__ 方法返回 NotImplemented 值,Python会自动尝试调用右侧对象的 __rmul__ 方法。"""
return self*k
def __truediv__(self,k):
"""返回数量除法的结果向量:self/k"""
return (1 / k) * self
def __pos__(self):
return 1 * self
def __neg__(self):
return -1 * self
u = MyVector([2,3])
v = MyVector([4,5])
print("u向量:",u)
print("v向量:",v)
print("向量u长度:",len(u))
print("向量v长度:",len(v))
print("%s + %s = %s" %(u,v,u+v))
print("%s - %s = %s" %(u,v,u-v))
print("%s / %s = %s" %(u,2,u/2))
print("%s * %s = %s" %(u,2,u*2))
print("-%s = "%(-v))
print("+%s = "%(+v))
u
(6)比较运算相关魔法方法
eq(self, other):定义对象的等于比较。
ne(self, other):定义对象的不等于比较。
lt(self, other):定义对象的小于比较。
le(self, other):定义对象的小于等于比较。
gt(self, other):定义对象的大于比较。
ge(self, other):定义对象的大于等于比较.
class MyObject:
def __init__(self, value):
self.value = value
def __eq__(self, other):
return self.value == other.value
def __ne__(self, other):
return self.value != other.value
def __lt__(self, other):
return self.value < other.value
def __le__(self, other):
return self.value <= other.value
def __gt__(self, other):
return self.value > other.value
def __ge__(self, other):
return self.value >= other.value
obj1 = MyObject(5)
obj2 = MyObject(5)
print(obj1 == obj2) # 输出:True
print(obj1 != obj2) # 输出:False
print(obj1 < obj2) # 输出:False
print(obj1 <= obj2) # 输出:True
print(obj1 > obj2) # 输出:False
print(obj1 >= obj2) # 输出:True
总结
本文,我们介绍了几种常用的python魔法方法的使用,总之,魔法方法使您能够更好地控制和自定义类的行为,使其适应您的特定需求。它们是Python中强大的工具,用于创建更灵活和强大的自定义类。下期,我们介绍更多常用的魔法方法。
参考:
【1】https://www.bilibili.com/video/BV1Hf4y1B7Bf/?spm_id_from=333.337.search-card.all.click