第 30 章 操作符重载 操作符重载
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
本章将继续深入探讨类的机制,重点是操作符重载。在前几章中,我们简要介绍了操作符重载;在这里,我们将补充更多细节,并介绍一些常用的重载方法。尽管我们不会逐一演示许多可用的运算符重载方法,但我们将在这里编码的那些方法是一个有代表性的样本,足以揭示 Python 类特性的可能性。
基础知识
实际上,"操作符重载 "仅仅意味着在类的方法中拦截内置的操作--当类的实例出现在内置操作中时,Python 会自动调用你的方法,而你的方法的返回值会变成相应操作的结果。下面回顾一下重载背后的主要思想:
操作符重载让类可以截取正常的 Python 操作。
类可以重载所有 Python 表达式运算符。
类还可以重载内置操作,如打印、函数调用、属性访问等。
重载使类实例更像内置类型。
重载是通过在类中提供特殊命名的方法来实现的。
换句话说,当类中提供了某些特殊命名的方法时,当类的实例出现在其关联表达式中时,Python 会自动调用它们。您的类将为由它创建的实例对象提供相应操作的行为。
我们已经了解到,运算符重载方法从来不是必需的,一般也没有缺省值(除了某些类从object 获取的少数几个方法);如果你没有编写或继承一个运算符重载方法,这只意味着你的类不支持相应的操作。不过,如果使用了这些方法,类就可以模仿内置对象的接口,从而显得更加一致。
构造函数和表达式:__init__和__sub__
请看 下面的简单示例:它的Number 类编码在文件number.py 中,提供了一个拦截实例构造的方法 (__init__),以及一个用于捕捉减法表达式的方法 (__sub__)。像这样的特殊方法是让您绑定到内置操作的钩子:
# File number.pyclass Number: def __init__(self, start):# On Number(start)self.data = start def __sub__(self, other):# On instance - otherreturn Number(self.data - other)# Result is a new instance>>>from number import Number# Fetch class from module>>>X = Number(5)# Number.__init__(X, 5)>>>Y = X - 2# Number.__sub__(X, 2)>>>Y.data# Y is new Number instance3
正如我们已经学过的,在这段代码中看到的__init__ 构造函数方法是 Python 中最常用的运算符重载方法;它存在于大多数类中,用来使用传递给类名的任何参数初始化新创建的实例对象。__sub__ 方法扮演了第 27 章介绍中__add__ 的二进制运算符角色,它截取减法表达式并返回一个新的类实例作为其结果 (同时运行__init__ )。
备注
从技术上讲,实例创建首先触发__new__ 方法,该方法创建并返回新的实例对象,然后将其传入__init__ 进行初始化。由于__new__ 有一个内置的实现,而且只在非常有限的角色中重新定义,所以几乎所有的 Python 类都通过定义一个__init__ 方法来初始化。我们将在第 40 章 学习元类时看到__new__ 的一个用例;尽管很少见,但它有时也用于自定义创建不可变类型的实例。 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access