Python实战技能-11-掌握魔法方法,构建强大的自定义对象-01

**Python中的魔法方法(Magic Methods)是用双下划线(例如__init__)实现的特殊方法,它们允许您自定义类的行为,构建更加强大的自定义对象,使类能够与Python内置函数和操作符进行交互。

  • 初始化方法:init
  • 构造方法:new
  • 使对象可迭代:通过实现 iternext 魔法方法,您可以使对象成为可迭代的,并能够使用for循环遍历它。
  • 支持上下文管理器:通过实现 enterexit 魔法方法,您可以使对象成为上下文管理器,从而支持with语句,以确保资源的正确分配和释放。
  • 运算符相关: 实现对象的加减乘除等,add,__mul__等
  • 比较对象:通过实现 eqltle 等魔法方法,您可以定义对象之间的比较操作,以便根据您的需求进行自定义比较。
  • 属性访问控制:通过实现 getattributesetattr 魔法方法,您可以自定义对象属性的访问和设置行为,从而实现更高级的属性控制。
  • 资源管理:使用 del 魔法方法,您可以在对象被销毁之前执行清理操作,例如关闭文件或释放资源。
  • 序列化:通过实现 getstatesetstate 方法,您可以定义对象的序列化和反序列化行为,以便将对象保存到文件或数据库中。
    总之,魔法方法使您能够更好地控制和自定义类的行为,使其适应您的特定需求。它们是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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值