English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Corso di base di Python

Controllo dei flussi in Python

Funzione in Python

Tipi di dati in Python

Operazioni di file in Python

Oggetti e classi in Python

Data e ora in Python

Conoscenze avanzate di Python

Manuale di riferimento di Python

Sovraccarico degli operatori in Python

Puoi cambiare il significato degli operatori in Python in base ai numeri operandi utilizzati. Questo metodo si chiama overloading degli operatori.

Cos'è l'overloading degli operatori in Python?

Python运算符Per le classi built-in. Ma lo stesso operatore ha comportamenti diversi per diversi tipi. Ad esempio, l'operatore + esegue l'addizione aritmetica di due numeri, la fusione di due liste e la connessione di due stringhe.

Questa funzione in Python permette che lo stesso operatore abbia significati diversi in base al contesto, detta overloading degli operatori.

Allora, cosa succede quando li usiamo con oggetti di classi definite dall'utente? Guardiamo la seguente classe, che tenta di simulare un punto in un sistema di coordinate bidimensionali.

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y

Ora, eseguiamo il codice e proviamo a sommare due punti nel shell di Python.

>>> p1 = Point(2,3)
>>> p2 = Point(-1,2)
>>> p1 + p2
Traceback (chiamata più recente in basso):
...
TypeError: operando non supportato per +: 'Point' e 'Point'

Wow! Ci sono molti errori. TypeError è stato scatenato perché Python non sa come sommare due oggetti Point.

Ma la buona notizia è che possiamo insegnare questo a Python tramite l'overloading degli operatori. Ma prima, dobbiamo avere una comprensione delle funzioni speciali.

Funzioni speciali in Python

Le funzioni della classe che iniziano con due trattini bassi __ sono chiamate funzioni speciali in Python. Questo perché non sono funzioni normali. La funzione __init__() che abbiamo definito sopra è una di esse. Viene chiamata ogni volta che creiamo un nuovo oggetto della classe. Python ha molte funzioni speciali.

Usando le funzioni speciali, possiamo rendere la nostra classe compatibile con le funzioni built-in.

>>> p1 = Point(2,3)
>>> print(p1)
<__main__.Point oggetto at 0x00000000031F8CC0>

L'output di stampa non ha raggiunto l'effetto previsto. Ma, se definiamo il metodo __str__() nella nostra classe, possiamo controllare il modo di output di stampa. Lo aggiungiamo alla nostra classe.

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def __str__(self):
        return "({0},{1})".format(self.x,self.y)

Ora, facciamo un altro tentativo con la funzione print().

>>> p1 = Point(2,3)
>>> print(p1)
(2,3)

 La prova ha dimostrato che è meglio, quando usiamo la funzione built-in str() o format(), chiamiamo lo stesso metodo format().

>>> str(p1)
'(2,3)'
>>> format(p1)
'(2,3)'

因此,当您执行str(p1)或format(p1)时,Python在内部执行p1.__str__()。因此得名,特殊函数。下面继续回到操作符重载。

在Python中重载+运算符

要重载+符号,我们将需要在类中实现__add__()函数。拥有权利的同时也被赋予了重大的责任。我们可以在此函数内做任何喜欢的事情。 但是返回坐标和的Point对象是明智的。

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def __str__(self):
        return "({0},{1})".format(self.x,self.y)
    
    def __add__(self,other):
        x = self.x + other.x
        y = self.y + other.y
        return Point(x,y)

现在,让我们再试一次。

>>> p1 = Point(2,3)
>>> p2 = Point(-1,2)
>>> print(p1 + p2)
(1,5)

实际上发生的是,当您执行p1 + p2时,Python会调用p1 .__ add __(p2),也就是Point .__ add __(p1,p2)。 同样,我们也可以重载其他运算符。 我们需要实现的特殊函数列表如下。

Python中运算符重载的特殊函数
运算符表达在内部
相加(+)p1 + p2p1 .__ add __(p2)
相减(-)p1-p2p1 .__ sub __(p2)
相乘(*)p1 * p2p1 .__ mul __(p2)
求幂(**)p1 ** p2p1 .__ pow __(p2)
相除(/)p1 / p2p1 .__ truediv __(p2)
整除(//)
p1 // p2p1 .__ floordiv __(p2)
求模 (%)p1%p2p1 .__ mod __(p2)
按位左移(<<)p1 << p2p1 .__ lshift __(p2)
按位右移(>>)p1 >> p2p1 .__ rshift __(p2)
按位与(and)p1 and p2p1 .__ and __(p2)
按位或(or)p1 | 2p1 .__ or __(p2)
按位异或(^)p1 ^ p2p1 .__ xor __(p2)
按位否(~)〜p1p1 .__ invert __()

Nel Python è possibile sovraccaricare gli operatori di confronto

Python不限制运算符重载为算术运算符。我们也可以重载比较运算符。

假设,我们想在Point类中实现小于运算符(<) ,让我们从原点比较这些点的大小,并为此目的返回结果。可以如下实现。

class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def __str__(self):
        return "({0},{1})".format(self.x,self.y)
    
    def __lt__(self,other):
        self_mag = (self.x ** 2) + (self.y ** 2)
        other_mag = (other.x ** 2) + (other.y ** 2)
        return self_mag < other_mag

尝试在Python shell中运行这些示例。

>>> Point(1,1) < Point(-2,-3)
True
>>> Point(1,1) < Point(0.5,-0.2)
False
>>> Point(1,1) < Point(1,1)
False

类似地,下面列出了我们需要实现以重载其他比较运算符的特殊函数。

Python中的比较运算符重载
操作符
表达式内部
小于(<)p1 <p2p1 .__ lt __(p2)
小于等于(<=)p1 <= p2p1 .__ le __(p2)

等于(==)

p1 == p2p1 .__ eq __(p2)
不等于(!=)p1!= p2p1 .__ ne __(p2)
大于(>)p1> p2p1 .__ gt __(p2)
大于等于(>=)p1> = p2p1 .__ ge __(p2)