2015-06-30 6 views
12

Stavo leggendo un codice che sembrava sostanzialmente in questo modo:È garantito che "__module__" sia definito durante la creazione della classe?

class Foo(object): 
    class_name = __module__.replace('_', '-') 

A me, che sembrava davvero strano (__module__, che importa?) Così sono andato e ho guardato il pitone data-model. Una ricerca rapida mostra che __module__ è una proprietà di oggetti classe e oggetti funzione. Tuttavia, non è disponibile lo __module__ nello spazio dei nomi globale (come può essere facilmente verificato semplicemente provando a guardarlo e osservando lo NameError che risulta ...).

Ho deciso di comunicare questo comportamento specifico di implementazione, ma come ultimo controllo, ho deciso di testare con altre implementazioni che ho a portata di mano. Si scopre che questo codice viene eseguito con

  • CPython 2.7.6
  • CPython 3.4.0
  • Jython 2.5.3
  • PyPy 2.2.1 (Python 2.7.3)

La mia domanda è se questo comportamento è effettivamente definito in qualsiasi punto del riferimento del linguaggio. Non sono sicuro del motivo per cui vorrei farlo, ma potrei fare affidamento su __module__ nello spazio dei nomi di creazione delle classi o tutti gli implementatori hanno deciso di farlo allo stesso modo?

Tutti Linux, ma dubito che le cose ...

+1

Impossibile trovare altro che il [Python 2.3 * Novità *] (https://docs.python.org/2/whatsnew/2.3.html#build-and-c-api-changes) dichiara * Se allocate dinamicamente gli oggetti di tipo nella vostra estensione, dovreste essere consapevoli di una modifica delle regole relative agli attributi '__module__' e' __name__'. In breve, vorrai assicurarti che il dizionario del tipo contenga una chiave "__module __"; rendendo il nome del modulo la parte del nome del tipo che porta fino al periodo finale non avrà più l'effetto desiderato. Per ulteriori dettagli, leggi la documentazione di riferimento dell'API o la fonte. * –

+0

Poiché tutti sembrano già supportarlo, potrebbe essere ragionevole chiedergli di essere standardizzato. – Veedrac

+0

@Veedrac - In realtà non sono d'accordo. È piuttosto strano in Python che i nomi vengano visualizzati solo nel tuo spazio dei nomi (non globale). per esempio. Non mi aspetto che vengano visualizzati nomi magici quando creo una funzione ... – mgilson

risposta

8

Che la documentazione non definire è che le classi avranno un attributo __module__. Sembra che CPython faccia ciò che definisce una variabile locale __module__ all'inizio del blocco di classe. Questa variabile diventa quindi una classe attribuita come qualsiasi altra variabile definita lì.

Non riesco a trovare alcuna documentazione dicendo che __module__ deve essere definito in questo modo. In particolare, non riesco a trovare alcuna documentazione che dichiari esplicitamente che l'attributo deve essere definito come variabile locale nel corpo della classe, invece di essere assegnato come attributo di classe in una fase successiva della creazione della classe. This answer in una domanda diversa indica che funziona in questo modo e mostra come appare nel bytecode. C'era a Jython bug che hanno risolto facendolo funzionare come CPython.

Sto indovinando che questo è un dettaglio di implementazione CPython che è stato trasferito ad altre implementazioni. Per quanto ne so, la documentazione in realtà non dice che __module__ deve essere disponibile all'interno del corpo della classe, solo successivamente sull'oggetto classe.

+1

Esattamente; che il nome è stato creato per primo nel corpo della classe non è garantito da nessuna parte nella lingua "specifica". –

+0

Anche questo era il mio pensiero. Come tale, ho consigliato agli autori iniziali del codice di fare affidamento sul '__file__' globale (e su vari utilit in' os') invece - anche se suppongo che potrei dire loro di usare '__name__' ... – mgilson

Problemi correlati