找回密码
 会员注册
查看: 19|回复: 0

python魔术方法大全——基础篇

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
69864
发表于 2024-9-10 06:12:38 | 显示全部楼层 |阅读模式
什么是魔术方法所谓魔法方法,它的官方的名字实际上叫specialmethod,是Python的一种高级语法,允许你在类中自定义函数,并绑定到类的特殊方法中。比如在类A中自定义__str__()函数,则在调用str(A())时,会自动调用__str__()函数,并返回相应的结果。docs.python.org/3/reference…我们常常看到的MagicMethods这个名字,在官方的文档里是没有出现过的。当然无论是magicmethods还是魔术方法,这些词都被广泛的使用着。所谓的魔术方法,是python提供的,让用户客制化一个类的方式,它顾名思义,就是定义在类里面的一些特殊的方法。这些specialmethod的特点,就是它的method的名字前后都有两个下划线,所以这些方法也被称为dundermethods。那包括这种前后两个下划线的形式,也叫做dunderscore,它的意思就是doubleunderscore。在我们平时写程序的时候,已经或多或少的接触过不少的魔术方法。比如:__init__就非常非常的常用。基础的魔术方法__new__和__init__首先,我们来聊一下__new__和__init__。这两个方法,可以让你改变从一个类建立一个对象时候的行为,这两个也比较容易被搞混。如果你不那么了解这两个方法的机制本身,你只需要记住,__new__是从一个class建立一个object的过程。而__init__是有了这个object之后,给这个object初始化的过程。classA:def__new__(cls,*args,**kwargs):print("__new__")returnsuper().__new__(cls,*args,**kwargs)def__init__(self):print("__init__")if__name__=='__main__':a=A()123456789101112输出结果为:__new____init__123我们可以看到__new__和__init__都被使用了。我们可以粗略的想象成:obj=__new__(A)__init__(obj)123如果我们在建立object的时候传入了参数,则参数既会传给__new__,也会传给__init__。在我们实际的应用中,__new__函数用到的是相对较少的。如果你不需要客制化建立这个object的过程,你只需要初始化这个object,你只需要用到__init__。那什么时候用__new__呢?比如说,我要创建一个单例,或者一些和metaclass有关的才会用到__new__函数。单例模式是指在整个应用程序中,某个类只能有一个实例存在,且该实例可以被任何模块访问到。这种模式的应用场景包括数据库连接池、日志对象等需要全局唯一性的对象。简单单例以下是一个简单的单例模式的示例代码:classSingleton:_instance=Nonedef__new__(cls):ifnotcls._instance:cls._instance=super().__new__(cls)returncls._instance12345678在这个例子中,我们定义了一个名为Singleton的类。它包含一个类变量_instance,该变量用于存储唯一实例的引用。在__new__方法中,我们检查_instance是否为None。如果是,则创建一个新的实例并将其分配给_instance。如果不是,则直接返回_instance,而不创建新的实例。通过这种方式,我们可以确保在应用程序中只有一个Singleton实例。要使用它,只需创建一个Singleton对象即可:s1=Singleton()s2=Singleton()print(s1iss2)#输出True12345以上代码输出结果为True,说明s1和s2引用的是同一个实例,即单例模式实现成功。__new__和元类(metaclass)在Python中,__new__()和元类(metaclass)之间有着紧密的联系,它们都是用来控制类的创建过程的。元类是Python中的一个高级特性,它允许我们在创建类的过程中动态地修改类。元类可以通过定义__new__()方法来控制类的实例化过程。在Python中,当我们通过class关键字定义一个新的类时,Python解释器会自动调用元类来实例化类对象。元类在实例化类对象之前,先调用类的__new__()方法来创建类的实例,然后再调用__init__()方法来初始化实例。在Python中,使用__call__()方法可以实现将类的实例对象作为函数调用的效果,类似于调用一个函数。当我们调用一个类的实例对象时,Python会自动调用这个实例对象的__call__()方法,从而实现了将类的实例对象作为函数调用的效果。通过在类的__call__()方法中间接调用类的__new__()方法和__init__()方法,可以实现单例模式。具体而言,每次调用类的实例对象时,都会先检查已经创建的实例对象是否存在,如果存在则直接返回该实例对象,如果不存在则通过调用__new__()方法和__init__()方法来创建一个新的实例对象,并将其存储下来。由于每次都返回同一个实例对象,因此实现了单例模式。以下是一个使用元类和__call__()方法实现单例模式的示例代码:classSingletonType(type):_instances={}def__call__(cls,*args,**kwargs):ifclsnotincls._instances:cls._instances[cls]=super().__call__(*args,**kwargs)returncls._instances[cls]classMyClass(metaclass=SingletonType):pass1234567891011在上述代码中,我们首先定义了一个元类SingletonType,这个元类重写了__call__()方法,用于控制类的实例化过程。在__call__()方法中,我们首先检查_instances字典中是否已经有该类的实例对象,如果已经存在,则直接返回该实例对象;如果不存在,则通过调用父类的__call__()方法创建一个新的实例对象,并将其存储到_instances字典中,然后返回该实例对象。接下来,我们定义了一个类SingletonClass,并将其元类设置为SingletonType。由于SingletonType的__call__()方法控制着SingletonClass的实例化过程,因此每次创建SingletonClass的实例对象时,都会经过SingletonType的__call__()方法来进行处理,从而实现了单例模式。下面是一个示例,演示了如何使用SingletonClass类来创建实例:a=SingletonClass()b=SingletonClass()print(aisb)#True12345由于SingletonClass类是一个单例类,因此a和b都是同一个实例对象,所以aisb的结果为True。所以必要时,我们可以通过元类和__new__方法来控制类的创建过程。__new__是创建object,因此它是有返回值的,必须返回这个object。而__init__没有返回值,__init__函数里面的self就是你要初始化的对象。__del____del__()是delete的缩写,这是析构魔术方法。当一块空间没有了任何引用时默认执行__del__回收这个类地址,一般我们不自定义__del__,有可能会导致问题触发时机:当对象被内存回收的时候自动触发,有下面两种情况:页面执行完毕回收所有变量当多个对象指向同一地址,所有对象被del的时候功能:对象使用完毕后资源回收参数:一个self接受对象返回值:无注意:程序自动调用__del__()方法,不需要我们手动调用。python中对象的释放是比较复杂的。__del__和关键字del是没有关系的,我们看到delo没有触发__del__。__del__()和del关键字是两个不同的概念,虽然它们都与对象的销毁相关。del是Python的一个关键字,用于删除变量或对象的引用。当我们执行delobj语句时,Python会将对象obj的引用计数减1,如果引用计数为0,则对象被销毁。del关键字并不会直接调用对象的__del__()方法,它只是将对象的引用计数减1,由Python自动决定是否调用__del__()方法。__del__()方法是一个特殊方法,用于在对象被销毁时执行一些清理任务。当对象的引用计数为0时,Python会自动调用该对象的__del__()方法进行清理。__del__()方法在对象被销毁前最后一次被调用,我们可以在这个方法中执行一些需要进行清理的操作,如释放资源、关闭文件等。需要注意的是,__del__()方法不是必须的,大多数情况下,Python会自动处理对象的销毁和内存管理,我们不需要手动定义__del__()方法。如果我们确实需要进行一些特殊的清理任务,应该尽量避免使用__del__()方法,而是使用上下文管理器、with语句等方式来管理资源和清理任务。__repr__和__str____repr__(self)和__str__(self)都是用于返回对象的字符串表示形式,但它们的用途不同。__repr__(self)主要用于调试和开发,而__str__(self)则主要用于用户友好的输出。举个例子,考虑下面的Python类:classPerson:def__init__(self,name,age):self.name=nameself.age=agedef__repr__(self):returnf"Person(name={self.name},age={self.age})"def__str__(self):returnf"{self.name}is{self.age}yearsold"123456789101112在这个例子中,__repr__返回一个类似于构造函数调用的字符串,用于显示对象的内部状态。而__str__则返回一个可读的字符串,用于显示对象的外部状态。例如:>>>person=Person("Alice",25)>>>print(person)#调用__str__Aliceis25yearsold>>>person#调用__repr__Person(name=Alice,age=25)123456这样,在调试和开发时,我们可以使用__repr__方法来查看对象的内部状态,而在用户友好的输出中使用__str__方法来提供易于理解的字符串表示形式。在实际使用中,我们可以通过内置函数repr()和str()来分别获取对象的__repr__和__str__表示形式。例如:p=Person("Alice",25)print(repr(p))#Person('Alice',25)print(str(p))#Alice(25yearsold)12345__repr__()是__str__()的“备胎”,如果找不到__str__()就会找__repr__()方法。%r默认调用的是__repr__()方法,%s调用__str__()方法__formate____format__方法是Python中用于格式化对象输出的特殊方法。它可以让我们在使用字符串格式化方法(如str.format()、f-string等)输出对象时自定义输出格式。__format__方法有两个参数,分别为格式字符串和格式参数。格式字符串用于指定输出格式,格式参数则是要输出的参数值。其中,格式字符串是一个包含格式说明符的字符串,可以使用大括号{}来指定要输出的参数,并在大括号中使用冒号:来指定参数的格式。下面是一个简单的例子,展示如何在类中定义__format__方法来控制输出格式:classPoint:def__init__(self,x,y):self.x=xself.y=ydef__format__(self,format_spec):ifformat_spec=="r":returnf"({self.y},{self.x})"else:returnf"({self.x},{self.y})"p=Point(1,2)print("Formattedpoint:{:r}".format(p))123456789101112131415在上面的例子中,我们定义了一个Point类,包含x和y两个属性。我们在类中定义了__format__方法,用于控制输出格式。如果格式字符串为"r",则输出(y,x)的格式;否则输出(x,y)的格式。在最后一行,我们使用str.format()方法并传入"!r"参数来触发__format__方法,输出结果为Formattedpoint2,1)。需要注意的是,如果我们定义了__format__方法,但在格式字符串中没有使用相应的格式说明符,那么__format__方法将不会被调用。此外,我们还可以在类中定义其他特殊方法来控制对象的输出格式,例如__str__、__repr__等。如果你对Python感兴趣,想要学习python,这里给大家分享一份Python全套学习资料,都是我自己学习时整理的,希望可以帮到你,一起加油!😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓Python全套学习资料1️⃣零基础入门①学习路线对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。②路线对应学习视频还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~③练习题每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!2️⃣国内外Python书籍、文档①文档和书籍资料3️⃣Python工具包+项目源码合集①Python工具包学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!②Python实战案例光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!③Python小游戏源码如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!4️⃣Python面试题我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。5️⃣Python兼职渠道而且学会Python以后,还可以在各大兼职平台接单赚钱,各种兼职渠道+兼职注意事项+如何和客户沟通,我都整理成文档了。上述所有资料⚡️,朋友们如果有需要的,可以扫描下方👇👇👇二维码免费领取🆓
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-7 07:07 , Processed in 0.888665 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表