Python面向对象——类的魔法方法

本文讲述Python面向对象的高级知识------类的魔法方法。阅读本文有助于理解源码!

一、什么是魔法方法

魔法方法(Magic Methods)是 Python 类中以双下划线开头和结尾(如 __init__)的特殊方法,由 Python 解释器在特定语法或操作触发时自动调用。它们定义了对象在语言层面的行为协议(Protocol),使得自定义类能够模拟内置类型(如 intlistdict)的语义,从而支持运算符重载、容器行为、上下文管理、字符串表示等核心功能。

看完这个定义,你肯定可以想到 __init__方法 没错这就是最常见的一个魔法方法,在类实例化时才会执行。

所以只要是以 __func__这样格式的就是魔法方法。

由于魔法方法太多,本文只挑选了六个常用的进行讲解。

python 复制代码
class Student:
    def __init__(self):
        self.name = '小白'
        self.gender = '男'
        self.age = 18


stu = Student()

二、四个魔法方法

【1】new()方法

new()方法是在 Python 中定义一个类的时候可以定义的一个特殊方法。

它被用来创建一个类的新实例(对象)。

你可能认为创建一个新的实例 一般是通过调用类的构造函数 init() 来完成的

然而,通过类名()创建对象时,在自动执行 init() 方法前,会先执行 object.new 方法,内存中开辟对象空间并返回该对象然后,Python 才会调用 init() 方法来对这个新实例进行初始化。

小例子

运行这段代码,你会发现先打印__new__里面的语句,再打印__init__的语句。

**注意:**一定要返回 object.new(cls) 这一句。为什么呢? 因为上面提到过 new 要在内存开辟对象空间并返回该对象。如果不返回,那么init方法中拿不到这个对象就无法进行赋值,就不会执行该方法,读者可以将这句注释 再运行看看

python 复制代码
class Student(object):
    def __new__(cls, *args, **kwargs):
        print("执行__new__方法")
        return object.__new__(cls) # 如果没有这行回怎么样

    def __init__(self):
        print("执行__init__方法")
        self.name = '小白'
        self.gender = '男'
        self.age = 18


stu = Student()

new_()方法的主要作用是创建实例对象,它可以被用来控制实例的创建过程。相比之下,init() 方法主要用于初始化实例对象。

new() 方法在设计模式中常常与单例模式结合使用,用于创建一个类的唯一实例。单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。

例子:

python 复制代码
class Singleton:
    _instance = None
    
    # 通过注释这段函数 运行两次
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance


# 创建实例
obj1 = Singleton()
obj2 = Singleton()

# 检查是否为同一个实例
print(obj1 is obj2)  # 输出: True

【2】__str__方法

改变对象的字符串显示。默认打印一个对象是返回其内存地址

如果我们使用 __str__方法 可以自定义我们想返回的内容

触发时机 : str(对象 ) print(对象)

例子:

注:这个str方法经常使用!!!

python 复制代码
class Student(object):

    def __init__(self):
        self.name = '小白'
        self.gender = '男'
        self.age = 18

    def __str__(self):
        return f"学生信息:姓名:{self.name},性别:{self.gender} 年龄:{self.age}"


stu = Student()

print(stu)
print(str(stu))

【3】eq 方法

用于比较两个类是否相等

触发时机 当对两个对象进行 == 运算时

重点理解:走谁的eq方法

python 复制代码
class Student(object):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
        self.age = 18

    def __eq__(self, other):
        print(f"走{self.name}的eq方法")
        return self.name == other.name


stu1 = Student('小白', '男')
stu2 = Student('小灰','女')
stu3 = Student('小黑','女')

print(stu1 == stu2)

【4】__item__系列 (重点)

在没有item系列魔法方法前,我们操作对象只能通过 对象实例.xxx

那有没有一种办法可以让我们像操作字典一样操作对象呢

在__item__系列中一共有3个方法需要我们掌握

getitem、setitem、delitem 对应三种操作 取值 赋值 删除值

例子:

python 复制代码
class Cache:
    def __init__(self):
        self.data = {}

    def __getitem__(self, key):
        return self.data[key]

    def __setitem__(self, key, value):
        self.data[key] = value

    def __delitem__(self, key):
        del self.data[key]

    def __contains__(self, key):
        return key in self.data

在上述例子中,我们创建了一个名为 Cache 的自定义类,并实现了 getitemsetitemdelitemcontains 这些特殊方法。

使用这个自定义的缓存类,我们可以像操作字典一样操作缓存数据,例如:

python 复制代码
cache = Cache()  
#存储数据  
cache['key1'] = 'value1'  
cache['key2'] = 'value2'  
  
#获取数据  
print(cache['key1'])  
print(cache['key2'])  
  
print("key1" in cache)  
  
del cache['key1']  
  
print("key1" in cache)

通过实现这一系列特殊方法,我们可以使用类似于字典的语法来访问和操作缓存对象。这样,我们可以更方便地存储、获取和删除缓存数据,同时也可以使用其他字典操作,如检查键是否存在。

三、总结

目前遇见最多的是str喝item系列魔法方法,后续这个文章还会继续更新我遇到的且有用的魔法方法。举个例子,我在研究simplejwt的源码发现底层就是使用了 str和item系列方法

相关推荐
Joker Zxc1 小时前
【前端基础(Javascript部分)】6、用JavaScript的递归函数和for循环,计算斐波那契数列的第 n 项值
开发语言·前端·javascript
kkkkatoq2 小时前
JAVA中的IO操作
java·开发语言
Highcharts.js2 小时前
React 图表如何实现下钻(Drilldown)效果
开发语言·前端·javascript·react.js·前端框架·数据可视化·highcharts
chushiyunen2 小时前
python中的魔术方法(双下划线)
前端·javascript·python
s09071362 小时前
【声纳成像】基于滑动子孔径与加权拼接的条带式多子阵SAS连续成像(MATLAB仿真)
开发语言·算法·matlab·合成孔径声呐·后向投影算法·条带拼接
深蓝轨迹2 小时前
@Autowired与@Resource:Spring依赖注入注解核心差异剖析
java·python·spring·注解
不想看见4042 小时前
C++八股文【详细总结】
java·开发语言·c++
人工智能AI技术2 小时前
Python 3.14.3更新!内存优化与安全补丁实战应用
python
2401_891655812 小时前
此电脑网络位置异常的AD域排错指南的技术文章大纲
开发语言·python·算法