[Python] Import vs execfile
Alessandro Dentella
sandro a e-den.it
Mer 14 Ago 2013 19:27:26 CEST
Grazie Enrico dell'ottima diagnosi,
Non avevo affatto valutato le implicazioni di chiamare execfile()
dall'interno di una funzione. All'inizio mi avevi anche persuaso a restare
sull'uso di import, dopo avere risolto il problema come vedi più avanti mi è
tornato il dubbio, per l'unico vantaggio di essere sicuro che non ci siano
conflitti con altri moduli dai nomi semplici come models, layout e hooks. In
particolare io avevo già 'layout' nel mio path e questo mi creava ulteriori
problemi.
On Wed, Aug 14, 2013 at 05:39:34PM +0200, enrico franchi wrote:
> In particolare quello che succede e' che secondo documentazione
> execfile non fa la cosiddetta "module administration". Non crea
> nemmeno un nuovo modulo. Ovviamente quindi quando chiedi __file__ da
> fuori da un modulo hai eccezione, quando lo chiedi da dentro un
> modulo, hai quello del codice enclosing.
>
> Quello che fa e' equivalente ad avere piazzato un exec che esegue la
> stringa letta dal file. Che a naso non e' quello che vuoi.
in realtà, allo scopo di registrare un paio di oggetti mi basterebbe
> Guarda quello che fanno quegli import:
>
> $ cat foo.code
> from os import listdir
> $ python
> Enthought Canopy Python 2.7.3 | 64-bit | (default, Mar 25 2013, 15:52:02)
> [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
> Type "help", "copyright", "credits" or "license" for more information.
> >>> listdir
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> NameError: name 'listdir' is not defined
> >>> execfile('foo.code')
> >>> listdir
> <built-in function listdir>
Qui ho commesso la prima leggerezza, ero convinto che non passare globals e
locals fosse equivalente a passare {}, che comunque per quanto da te
evidenziato non andrebbe bene.
in particolare però la doc dice:
If two separate objects are passed as globals and locals, the code will be
executed as if it were embedded in a class definition.
che non mi è completamente chiaro cosa significhi, ma ho provato a evitare
che fossero diversi, chiamando la funzione così::
VARS = {}
execfile('models.py', VARS, VARS)
o più semplicemente::
execfile('models.py', {})
e tutto funziona correttamente. A questo punto gli import del file eseguito
vengono effettivamente aggiunti ai globals, non ai locals e la classe li
vede correttamente.
sandro
*:-)
PS: So che python3 non ha più execfile...
Maggiori informazioni sulla lista
Python