Qu'est-ce qu'une alternative à execfile en Python 3?

il semble qu'ils ont annulé en Python 3 tout le moyen facile de charger rapidement un script en supprimant execfile()

y a-t-il une alternative évidente que je ne vois pas?

246
demandé sur ideasman42 2009-01-12 20:23:36

12 réponses

selon la documentation , au lieu de

execfile("./filename") 

Utiliser

exec(open("./filename").read())

voir:

260
répondu Pedro Vagner 2018-02-02 02:27:32

Vous êtes seulement censés lire le fichier et exec le code vous-même. 2à3 actuel remplace

execfile("somefile.py", global_vars, local_vars)

comme

with open("somefile.py") as f:
    code = compile(f.read(), "somefile.py", 'exec')
    exec(code, global_vars, local_vars)

(l'appel de compilation n'est pas strictement nécessaire, mais il associe le nom du fichier à l'objet code, ce qui rend le débogage un peu plus facile.)

voir:

189
répondu Benjamin Peterson 2013-01-29 22:51:10

comme suggéré sur la liste de diffusion python-dev récemment, le module runpy pourrait être une alternative viable. Citant ce message:

https://docs.python.org/3/library/runpy.html#runpy.run_path

import runpy
file_globals = runpy.run_path("file.py")

il y a des différences subtiles à execfile :

  • run_path crée toujours un nouvel espace de noms. Il exécute le code comme un module, donc il n'y a pas de différence entre les globals et les locals (c'est pourquoi il n'y a qu'un argument init_globals ). Les variables globales sont retournés.

    execfile exécuté dans l'espace de noms courant ou de l'espace de noms donné. La sémantique de locals et globals , si elle est donnée, est similaire à celle des locaux et des globals à l'intérieur d'une définition de classe.

  • run_path peut non seulement exécuter des fichiers, mais aussi des eggs et des répertoires (voir sa documentation pour plus de détails).

41
répondu Jonas Schäfer 2014-06-17 10:06:15

alors que exec(open("filename").read()) est souvent donné comme une alternative à execfile("filename") , il manque pas mal de détails que execfile pris en charge.

la fonction suivante pour Python3.x est aussi proche que j'ai pu obtenir pour avoir le même comportement que l'exécution d'un fichier directement. Ça correspond à python /path/to/somefile.py .

def execfile(filepath, globals=None, locals=None):
    if globals is None:
        globals = {}
    globals.update({
        "__file__": filepath,
        "__name__": "__main__",
    })
    with open(filepath, 'rb') as file:
        exec(compile(file.read(), filepath, 'exec'), globals, locals)

# execute the file
execfile("/path/to/somefile.py")

Notes:

  • utilise la lecture binaire pour éviter l'encodage les questions de
  • garanti pour fermer le fichier (Python3.x avertit à ce sujet)
  • définit __main__ . if __name__ == "__main__"
  • définir __file__ est plus agréable pour les messages d'exception et certains scripts utilisent __file__ pour obtenir les chemins d'autres fichiers relatifs à eux.
  • prend facultatif les arguments globals & locals, en les modifiant en place comme execfile le fait-de sorte que vous pouvez accéder à toutes les variables définies en relisant les variables après exécution.

  • contrairement à execfile de Python2, ne modifie pas l'espace de noms actuel par défaut. Pour cela, vous devez explicitement passer dans globals() .

34
répondu ideasman42 2018-09-12 21:54:33

vous pourriez écrire votre propre fonction:

def xfile(afile, globalz=None, localz=None):
    with open(afile, "r") as fh:
        exec(fh.read(), globalz, localz)

si vous en aviez vraiment besoin...

17
répondu Evan Fosmark 2013-01-30 02:09:04

celui-ci est mieux, car il prend les globals et les locaux de l'appelant:

import sys
def execfile(filename, globals=None, locals=None):
    if globals is None:
        globals = sys._getframe(1).f_globals
    if locals is None:
        locals = sys._getframe(1).f_locals
    with open(filename, "r") as fh:
        exec(fh.read()+"\n", globals, locals)
16
répondu Noam 2010-05-17 12:43:26

Si le script que vous voulez charger dans le même répertoire que celui que vous exécutez, peut-être "importer" va faire le travail ?

si vous avez besoin d'importer dynamiquement le code de la fonction intégrée _ _ import__ et le module imp sont à regarder.

>>> import sys
>>> sys.path = ['/path/to/script'] + sys.path
>>> __import__('test')
<module 'test' from '/path/to/script/test.pyc'>
>>> __import__('test').run()
'Hello world!'

test.py:

def run():
        return "Hello world!"

si vous utilisez Python 3.1 ou plus tard, vous devriez aussi jeter un oeil à importlib .

11
répondu ascobol 2012-01-26 17:11:05

voici ce que j'avais ( file est déjà assigné au chemin du fichier avec le code source dans les deux exemples):

execfile(file)

voici ce que je l'ai remplacé par:

exec(compile(open(file).read(), file, 'exec'))

ma partie préférée: la seconde version fonctionne très bien en Python 2 et 3, ce qui signifie qu'il n'est pas nécessaire d'ajouter la logique dépendante de la version.

6
répondu ArtOfWarfare 2014-10-07 13:39:03

notez que le modèle ci-dessus échouera si vous utilisez des déclarations d'encodage PEP-263 ce ne sont pas des ascii ou des utf-8. Vous devez trouver le codage des données, et l'encoder correctement avant de le remettre à exec ().

class python3Execfile(object):
    def _get_file_encoding(self, filename):
        with open(filename, 'rb') as fp:
            try:
                return tokenize.detect_encoding(fp.readline)[0]
            except SyntaxError:
                return "utf-8"

    def my_execfile(filename):
        globals['__file__'] = filename
        with open(filename, 'r', encoding=self._get_file_encoding(filename)) as fp:
            contents = fp.read()
        if not contents.endswith("\n"):
            # http://bugs.python.org/issue10204
            contents += "\n"
        exec(contents, globals, globals)
5
répondu Eric 2011-04-13 00:43:54

aussi, bien que ce ne soit pas une solution Python pure, si vous utilisez IPython( comme vous le devriez probablement de toute façon), vous pouvez le faire:

%run /path/to/filename.py

ce qui est tout aussi facile.

3
répondu R S 2017-01-15 06:10:24

je suis juste un internaute novice ici donc peut-être que c'est de la pure chance si je trouve ceci:

Après avoir essayé d'exécuter un script à partir de l'interprète invite >>> avec la commande

    execfile('filename.py')

pour lequel j'ai obtenu un "NameError: nom' execfile 'n'est pas défini" j'ai essayé un très basique

    import filename

il a bien fonctionné :-)

j'espère que cela peut être utile et je vous remercie tous pour les grands conseils, les exemples et toutes ces magistrales commenté morceaux de code qui sont une grande source d'inspiration pour les nouveaux arrivants !

J'utilise Ubuntu 16.014 LTS x64. Python 3.5.2 (par défaut, le 17 Novembre 2016, 17:05:23) [GCC 5.4.0 20160609] sur linux

2
répondu Claude 2017-02-11 23:23:28

localisez la route de votre installation de dossier (je l'ai en C:\python34) puis exécutez sur un shell cmd régulier

   set path=%path%;c:\python34

maintenant quand vous initiez un shell, passez à C:\python34\myscripts et utilisez la commande classique

 python filename.py 
-2
répondu Weapon X 2015-02-04 20:42:51