python __reduce__魔法方法_Python魔法方法指南

有很多人说学习Python基础之后不知道干什么,不管你是从w3c还是从廖雪峰的教程学习的,这些教程都有一个特点:只能引你快速入门,但是有关于Python的很多基础内容这些教程中都没介绍,而这些你没学习的内容会让你在后期做项目的时候非常困惑。就比如下面这篇我要给大家推荐的文章所涉及的内容,不妨你用一天时间耐心看完,把代码都敲上一遍。--11:33更新--很多人想要我的一份学习笔记,所以在魔法指南之前...
摘要由CSDN通过智能技术生成

有很多人说学习Python基础之后不知道干什么,不管你是从w3c还是从廖雪峰的教程学习的,这些教程都有一个特点:只能引你快速入门,但是有关于Python的很多基础内容这些教程中都没介绍,而这些你没学习的内容会让你在后期做项目的时候非常困惑。就比如下面这篇我要给大家推荐的文章所涉及的内容,不妨你用一天时间耐心看完,把代码都敲上一遍。

--11:33更新--

很多人想要我的一份学习笔记,所以在魔法指南之前,我放上我自己学习过程中提炼的一些知识点和自己的感悟,如果不想看我的笔记可以直接跳过。

从入门到进阶,一个很重要的点就是Python中的魔法方法,魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。它们经常是两个下划线包围来命名的(比如 __init__/__new__等等),Python的魔法方法是非常强大的。

如果你学习过Java,那你会发现Python中的魔法方法像是Java中的重载,Python中的魔法方法可以理解为:对类中的内置方法的重载,注意这里不是重写。

举个例子,Python中有个比较操作符==用来比较两个变量的大小,而这个操作符是通过内置函数__eq__来实现的,所以我们只需要通过改变这个内置函数代码,就可以改变重新定义这个操作符的行为。

我们定义一个类Word,继承自str类,现需要重新定义该类的操作符==,使这个操作符用来判断两个字符串长度是否相等,而不是通过字母顺序判断两个字符串是否相等。注意该变化只适用于Word类,而不适用于其它类。

v2-7ce999561b15a78da9ac78765d06fe5e_b.png

再举个例子:Python中的__new__方法是对象实例化时调用的第一个方法,该方法仅读取一个cls参数后再把其他参数都传给用于指明对象初始化行为的__init__方法,也就是说我们可以在一个对象初始化之前进行其他操作,比如检查是否合法等;而另一个方法__del__可以用来销毁对象,定义了对象被垃圾回收的行为,我们可以利用该方法进行资源回收等操作。

我们可以通过重写__new__方法实现一个单例模式,在每次实例化之前检查该对象是否有已有实例。

v2-86d4a9b4b3a26af9548e37c0b4598ec0_b.png

通过这两个例子相信你已经对Python的魔法方法比较理解了,但是Python中的魔法方法远不止两三个,而在官方文档中,也没有一个比较详细的归纳,所以这里参考译文(在此文的最后部分)做一个简单的汇总,希望大家可以根据这个汇总的表单对其中的魔法方法进行尝试,下次再看到这样的用法也就不足为奇了。

由于版本等问题,以下的表格对译文的内容进行了修改、删减。

v2-74b43859d669589d953fa59eb7c57778_b.png

以上是关于操作符运算符的方法,我们很少会改变这些魔法方法除非你真的需要改变他们,当然还有一些我们可能会用到的:

1、__str__/__repr__

__str__定义对类的实例调用str()时的行为。而__repr__定义对类的实例调用repr()的行为,这两者的区别就是repr面向机器,str面向人。定义类的输出的时候经常会使用这两个其中的魔法。

v2-3fcf19069d014dc969f120b38f7f01a1_b.png

2、__getattr__/__setattr__/__del__attr

使用这三个方法你可以随时修改、删除、添加类属性或值,是不是觉得大吃一惊?

v2-76a05aa3154a064d727cb8ef53190382_b.png

Python中魔法函数常用的大体如上,也还有一些没有提到,你可以继续往下阅读。

以下是译文的原文正文

原作者:Rafe Kettler ; 翻译:hit9

1、简介

本指南归纳于我的几个月的博客,主题是 魔法方法 。

什么是魔法方法呢?它们在面向对象的Python的处处皆是。它们是一些可以让你对类添加“魔法”的特殊方法。 它们经常是两个下划线包围来命名的(比如 __init__ , __lt__ )。但是现在没有很好的文档来解释它们。 所有的魔法方法都会在Python的官方文档中找到,但是它们组织松散。而且很少会有示例(有的是无聊的语法描述, 语言参考)。

所以,为了修复我感知的Python文档的缺陷,我开始提供更为通俗的,有示例支持的Python魔法方法指南。我一开始 写了一些博文,现在我把这些博文总起来成为一篇指南。

希望你喜欢这篇指南,一篇友好,通俗易懂的Python魔法方法指南!

2、构造方法

我们最为熟知的基本的魔法方法就是 __init__ ,我们可以用它来指明一个对象初始化的行为。然而,当我们调用 x = SomeClass() 的时候, __init__ 并不是第一个被调用的方法。事实上,第一个被调用的是 __new__ ,这个 方法才真正地创建了实例。当这个对象的生命周期结束的时候, __del__ 会被调用。让我们近一步理解这三个方法:

__new__(cls,[...)

__new__ 是对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 __init__ 。 __new__ 很少使用,但是也有它适合的场景,尤其是当类继承自一个像元组或者字符串这样不经常改变的类型的时候。我不打算深入讨论 __new__ ,因为它并不是很有用, Python文档 中 有详细的说明。

__init__(self,[...])

类的初始化方法。它获取任何传给构造器的参数(比如我们调用 x = SomeClass(10, ‘foo’) , __init__ 就会接到参数 10 和 ‘foo’ 。 __init__ 在Python的类定义中用的最多。

__del__(self)

__new__ 和 __init__ 是对象的构造器, __del__ 是对象的销毁器。它并非实现了语句 del x (因此该语句不等同于 x.__del__())。而是定义了当对象被垃圾回收时的行为。 当对象需要在销毁时做一些处理的时候这个方法很有用,比如 socket 对象、文件对象。但是需要注意的是,当Python解释器退出但对象仍然存活的时候, __del__ 并不会 执行。 所以养成一个手工清理的好习惯是很重要的,比如及时关闭连接。

这里有个 __init__ 和 __del__ 的例子:

from os.path import join

class FileObject:

'''文件对象的装饰类,用来保证文件被删除时能够正确关闭。'''

def __init__(self, filepath='~', filename='sample.txt'):

# 使用读写模式打开filepath中的filename文件

self.file = open(join(filepath, filename), 'r+')

def __del__(self):

self.file.close()

del self.file

3、操作符

使用Python魔法方法的一个巨大优势就是可以构建一个拥有Python内置类型行为的对象。这意味着你可以避免使用非标准的、丑陋的方式来表达简单的操作。 在一些语言中,这样做很常见:

if instance.equals(other_instance):

# do something

你当然可以在Python也这么做,但是这样做让代码变得冗长而混乱。不同的类库可能对同一种比较操作采用不同的方法名称,这让使用者需要做很多没有必要的工作。运用魔法方法的魔力,我们可以定义方法 __eq__

if instance == other_instance:

# do something

这是魔法力量的一部分,这样我们就可以创建一个像内建类型那样的对象了!

3.1、比较操作符

Python包含了一系列的魔法方法,用于实现对象之间直接比较,而不需要采用方法调用。同样也可以重载Python默认的比较方法,改变它们的行为。下面是这些方法的列表:

__cmp__(self, other)

__cmp__ 是所有比较魔法方法中最基础的一个,它实际上定义了所有比较操作符的行为(<,==,!=,等等),但是它可能不能按照你需要的方式工作(例如,判断一个实例和另一个实例是否相等采用一套标准,而与判断一个实例是否大于另一实例采用另一套)。 __cmp__ 应该在 self < other 时返回一个负整数,在 self == other 时返回0,在 self > other 时返回正整数。最好只定义你所需要的比较形式,而不是一次定义全部。 如果你需要实现所有的比较形式,而且它们的判断标准类似,那么 __cmp__ 是一个很好的方法,可以减少代码重复,让代码更简洁。

__eq__`(self, other)

定义等于操作符(==)的行为。

__ne__(self, other)

定义不等于操作符(!=)的行为。

__lt__(self, other)

定义小于操作符(<)的行为。

__gt__(self, other)

定义大于操作符(>)的行为。

__le__(self, other)

定义小于等于操作符(<)的行为。

__ge__(self, other)

定义大于等于操作符(>)的行为。

举个例子,假如我们想用一个类来存储单词。我们可能想按照字典序(字母顺序)来比较单词,字符串的默认比较行为就是这样。我们可能也想按照其他规则来比较字符串,像是长度,或者音节的数量。在这个例子中,我们使用长度作为比较标准,下面是一种实现:

class Word(st

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值