Perché il corpo di una class viene eseguito al momento della definizione?

A differenza delle funzioni, il corpo di una class viene eseguito al momento della definizione:

class A(object): print 'hello' 

Su:

 hello 

Perché è così? È legato ai metodi @classmethod / @staticmethod e agli attributi di class?

Tutto viene eseguito a livello di modulo quando Python importa prima un modulo. I corpi di funzione (e i corpi di espressione del generatore) sono l’ eccezione qui, non la regola. Python esegue tutto per creare gli oggetti contenuti in un modulo; come tutto in Python, le classi sono oggetti e anche le funzioni.

L’unica ragione per cui un corpo di class usa un object di codice separato è perché un corpo di class viene eseguito in uno spazio dei nomi separato, con lo spazio dei nomi che quindi forma gli attributi di class. I corpi di class non sono gli unici namespace di questo tipo; imposta e impone la comprensione, e in Python 3, le comprensioni delle liste vengono anche eseguite con uno spazio dei nomi separato, che circoscrive la loro gente del posto.

Quindi le funzioni e le espressioni del generatore sono l’eccezione, espressamente perché il loro intero scopo deve essere eseguito in un secondo momento. Si noti che la definizione della funzione viene eseguita:

 >>> import dis >>> dis.dis(compile('def foo(): pass', '', 'exec')) 1 0 LOAD_CONST 0 (", line 1>) 3 MAKE_FUNCTION 0 6 STORE_NAME 0 (foo) 9 LOAD_CONST 1 (None) 12 RETURN_VALUE 

Il bytecode MAKE_FUNCTION crea lì l'object funzione, insieme al codice byte memorizzato per quella funzione, e il risultato è associato al nome globale foo .

Qui gli oggetti di class non sono diversi; l'istruzione della class produce un object di class e, come parte di tale object, abbiamo bisogno di conoscere gli attributi dal corpo della class.

Se Python non ha eseguito il corpo della class, l'altro codice non ha potuto fare alcun uso di quei membri della class. Non è ansible accedere agli attributi di class (inclusi metodi di class e metodi statici), non è ansible impostare attributi di class, ecc.

Tutte le funzioni che fanno parte del corpo della class non sono ovviamente eseguite in quel momento. Proprio come le funzioni di primo livello, viene eseguito solo un bytecode MAKE_FUNCTION e il nome locale risultante (impostato con STORE_FAST ) viene quindi trasformato in un attributo di class, analogamente a un object di funzione globale associato a un globale con STORE_NAME .

Secondo le definizioni di class – documentazione di Python :

Una definizione di class è un’istruzione eseguibile. Prima valuta l’elenco di ereditarietà, se presente. Ogni elemento nell’elenco di ereditarietà deve valutare un object di class o un tipo di class che consente la sottoclass. La suite della class viene quindi eseguita in un nuovo frame di esecuzione (vedere la sezione Assegnazione di nomi e binding), utilizzando uno spazio dei nomi locale appena creato e lo spazio dei nomi globale originale. (Di solito, la suite contiene solo le definizioni di funzione.) Quando la suite della class termina l’esecuzione, la sua cornice di esecuzione viene scartata ma il suo spazio dei nomi locale viene salvato. Viene quindi creato un object class utilizzando l’elenco di ereditarietà per le classi di base e lo spazio dei nomi locale salvato per il dizionario degli attributi. Il nome della class è associato a questo object di class nello spazio dei nomi locale originale.