[Python] Problema con la condivisione e l'utilizzo di un dict globale

Marco Giusti marco.giusti a gmail.com
Sab 13 Nov 2010 14:23:28 CET


On Sat, Nov 13, 2010 at 12:48:25PM +0100, lex mlist wrote:
[...]
> > tu leghi (bind) il nome configuration allo scope locale. quando da
> > dentro la funzione cerchi il nome ``configuration``, lui lo trova nello
> > scope locale e ritorna quello, ovvero i parametri di configurazione, ma
> > dal modulo ``error`` tu ottieni la variabile che è associata allo scope
> > globale.
> >
> 
> Accipicchia che comportamento "strano" :s
> Non posso che chiedermi il perchè di un tale comportamento, si verifica solo
> all'interno delle classi o in presenza di qualunque scope non globale?
> (funzioni ed altro, se esiste)

i motivi di tale comportamento non li conosco, non sono un teorico di
linguaggi e a dire il vero non conosco neanche l'implementazione python.
questo comportamento si ha con le funzioni e quindi anche con i metodi,
al loro interno viene creato un nuovo scope prioritario rispetto a
quello globale.

pensa allo scope locale come un foglio trasparente sopra a quello
globale: puoi leggere quello che sta' sotto, ma quando vai a scrivere tu
in realtà scrivi sul foglio trasparente.
da qualche parte avevo letto un acronimo che spiegava l'ordine di
ricerca dei noi ma non lo ritrovo. doveva essere LOGB ovvero Local,
Outer, Global e Builtins.

una cosa simile si ha con le classi e le istanze: con ``self.v`` puoi
leggere un attributo di classe di nome ``v``, ma con ``self.v = 123``
vai a scrivere in un attributo di istanza.

> > python mette a disposizione
> > una variabile globale, ``__debug__``, che è sempre vera a meno di
> > eseguire l'interprete python con le opzioni di ottimizzazione, -O. in
> > quel caso crea dei file con bytecode ottimizzato .pyo, invece dei
> > classici .pyc, inoltre è interessante come viene ottimizzato il codice:
> >
> >        import dis
> >
> >        def error(msg):
> >                if __debug__:
> >                        print msg
> >
> >        error('exception...')
> >        dis.dis(error)
> >
> > prova a lanciare questo codice prima normalmente e poi con l'opzione -O.
> >
> 
> Wow! Sinceramente ci speravo in una variabile tipo quella, anche se non ci
> contavo troppo, a questo punto potrei usufruire della variabile __debug__,
> visto che ottimizza anche il bytecode finale. Ho provato a ripetere
> l'esempio con una variabile booleana "debug" e in nessun caso il codice
> viene ottimizzato.

l'ottimizzazione del bytecode python è molto superficiale, per quanto ne
sò tutto quello che viene fatto è la rimozione di alcuni statement: gli
``assert``, ``__debug__`` viene impostata a ``False`` e vengono
eliminati (azzerati?) tutti gli attributi ``__doc__`. il test sulla
variabile ``__debug__`` è un piccolo extra ma neanche troppo furbo,
tempo fa' non era in grado di eliminare questo statement:

	if __debug__ and var:
		...

ora non saprei.

> Mi sembra un ottimo compromesso aggiungere una semplice opzione -O per
> ottenere un insieme di benefici.
> L'opzione è da ripetere ad ogni esecuzione o basta la prima volta lasciando
> poi i .pyo? (a me comunque non ha salvato alcun .pyo, magari lo farà quando
> lo chiamano altri moduli)

hai ragione, il bytecode non viene mai scritto sul disco, probabilmente
è l'import di un modulo che fa' questo (cerca i .pyc, non li trova,
compila il .py, salva il bytecode sul disco, etc.)

semplicemente importa il modulo e ti verrà compilato e scritto sul .pyo
e pui utilizzare e distribuire questi moduli esattamente come avresti
fatto con i .pyc.

	python -O -c 'import mymodule'

> Grazie ancora!

niente
m.

-- 
La vera terra dei barbari non è quella che non ha mai conosciuto
l'arte, ma quella che, disseminata di capolavori, non sa nè
apprezzarli nè conservarli.
		-- Marcel Proust


Maggiori informazioni sulla lista Python