[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