2016-02-03 18 views
5

che ho osservato almeno 3 tipologie legate alle funzioni in Python 3:Qual è la differenza tra una "funzione", un "metodo" e un "metodo associato" in Python 3?

>>> class A(): 
... def f(): pass 
... 
>>> A.f 
<function A.f at 0x7fcaef304268> 
>>> A().f 
<bound method A.f of <__main__.A object at 0x7fcaef2fae80 
>>> set.union 
<method 'union' of 'set' objects> 

mi chiedo qual è la differenza tra la 'funzione', 'metodo' e 'il metodo bound'? 'Metodo' è un tipo equivalente a 'metodo non associato' in Python 2?

risposta

5

"metodo" è un tipo equivalente a "metodo non associato" in Python 2?

Tipo-a-tipo-a. Ma non proprio. È un oggetto method_descriptor definito nel codice C. È un metodo non associato, ma non il tipo trovato in Python 2.

Per i tipi Python scritti C, tutti i "metodi" sono in realtà funzioni C. L'oggetto <method 'name' of 'type' objects> trovato è un oggetto speciale che è possibile utilizzare per chiamare tale funzione in base a un'istanza e ulteriori argomenti, proprio come fa l'oggetto function per le classi Python personalizzate. L'oggetto è definito in C nello PyMethodDescr_Type structure. Implementa il descriptor protocol, proprio come fanno le funzioni.

Python definisce diversi altri tipi di descrittori; se si utilizza __slots__, ogni attributo è un dsescriptor di tipo member_descriptor (vedere PyMemberDescr_Type structure), mentre classmethod, property e staticmethod sono forse oggetti descrittori più noti.

In Python 2, legati e non legati metodi sono in realtà solo un tipo, instancemethod (definita dal PyMethod_Type structure); verrà segnalato come associato se è impostato l'attributo __self__ (im_self). In Python 3 l'utilizzo di una funzione come descrittore non produce semplicemente oggetti metodo senza il set __self__; chiamando invece function.__get__() senza istanza si torna nuovamente alla funzione.

L'unico motivo per cui Python 2 restituisce metodi non associati è impone un controllo del tipo; il primo argomento deve essere un'istanza della classe (o una sua sottoclasse). Questo non ha avuto molto senso per il codice Python che supporta la digitazione anatra, quindi in Python 3 la restrizione è stata rimossa. Tuttavia, con il codice C non è possibile utilizzare la digitazione anatra, è comunque necessario limitare il tipo ed è per questo che tipi-C restituiscono ancora un oggetto method_descriptor che applica questa restrizione.