一种运算符对于不同类型的对象,有不同的使用方式。例如,+
用于整型对象,表示两个数相加;用于字符串,表示连接这两个字符串。
x, y = 10, 20
print(x + y) # 30
a,b = 'John', 'Wick'
print(a + b) # John Wick
+
运算符因操作对象的类型的不同而执行不同的操作,这种特性称为重载。
运算符的功能因其操作数据的类型而异,我们称之为重载。
+
运算符可以用于任意两个对象的相加吗?我们来试试看。
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
v1 = Vector(3, 4)
v2 = Vector(5, 6)
v1 + v2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-08104d7e1232> in <module>
----> 1 v1 + v2
TypeError: unsupported operand type(s) for +: 'Vector' and 'Vector'
运行这段代码会报错。为什么呢?这是因为+
运算符不知道如何把两个 Vector 类的对象相加。
在本文中,我们将研究如何将既有的运算符用于自定义对象的操作,同时我们要牢记 Python 语言对操作符重载的一些限制性规则。
这些限制性规则有:
- 不允许创建新的运算符,只能重载已有的那些运算符
- 不允许重载已有数据类型(如 tuple 、 string 、 list)的某些运算符操作
- 某些运算符不能重载,例如 is, or, and, not
在开始学习运算符重载前,我们需要了解 Python 数据模型 和 特殊方法。
Python 数据模型可以看作一种 “Python 设计方式”或 “Python 框架”。它告诉你 Python 如何管理对象以及如何对它们进行操作。它描述了一系列 API,你可以使用这些 API 使你定义的对象具备已有数据类型的某些功能,并且可以使用大多数 Python 语言的特性,而且不必实现它们。
特殊方法→
当你使用 len(collection),Python 解释器调用的是 collection.len()
方法。这里的 len() 就是一个特殊方法。
特殊方法开头和结尾都是 __
,意为只能由 Python 解释器调用,除非你在进行元编程,不然不要直接调用它。
在 Python 语言中,我们可以使用特殊方法来实现运算符重载。
现在我们进行编码,使 Vector 对象支持+
运算符。
当我们调用+
这个运算符时,Python 解释器调用了 add(self, other)
这个特殊方法。所以,在我们定义的类中实现 add() 方法,就可以支持+
运算符。
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x , self.y + other.y)
def __repr__(self):
return f'Vector({self.x}, {self.y})'
v1 = Vector(3, 4)
v2 = Vector(5, 6)
v1 + v2
>>> Output: Vector(8, 10)
你会发现,我们的类已经支持 +
运算符,在这个类中还实现了 repr() 方法,当我们调用 print() 方法,解释器调用 str() 方法,如果我们没有提供 repr() 的实现,就会调用原来的 repr() 方法。
注意:除了重载类似于 +=
的赋值运算符外,一定要返回一个新建的对象。
再举个重载运算符的例子
当我们使用==
运算符时,Python 解释器会调用eq(self, other)
这个特殊方法,所以我们通过实现 eq()
方法就可以使某个类支持==
运算符。
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x , self.y + other.y)
def __repr__(self):
return f'Vector({self.x}, {self.y})'
def __eq__(self, other):
return self.x == other.x and self.y == other.y
v1 = Vector(3, 4)
v2 = Vector(5, 6)
v1 == v2
>>> Output: False
v3 = Vector(3,4)
v1 == v3
>>> Output: True
在 Python 中,使用特殊方法可以轻松实现运算符重载。关键在于理解数据模型和特殊方法。
这些方法能让你从 Python 的惯用特性中受益,并且能利用强大的标准库。
总结
我们从理解什么是运算符重载开始,接着讨论了 Python 中运算符重载的一些限制条件、数据模型和特殊方法,然后在 Vector 类中实现了运算符重载。