J'utilise l'instruction Je réalise que EXEC CODE> dans certains CODE PYTHON 2, et j'essaie de rendre ce code compatible avec Python 2 et Python 3, mais dans Python 3,
EXEC code> a changé d'une instruction dans une fonction. Est-il possible d'écrire du code compatible avec Python 2 et 3? J'ai lu sur Python 2 et Python 3 Dual Development , mais je suis intéressé par des solutions spécifiques au
Exec code> Énoncé / Modifications de la fonction. P>
EXEC code> est généralement découragé, mais je construisais un plug-in Eclipse qui implémente le codage en direct au-dessus de PYDEV. Voir le Page du projet pour plus de détails. P>
3 Réponses :
J'ai trouvé plusieurs options pour ce faire, avant de poster Antti Publié sa réponse que Python 2 prend en charge le python 3 Syntaxe de fonction Exec .
La première expression peut également être un tuple de longueur 2 ou 3. Dans ce cas, les pièces en option doivent être omises. Le formulaire
EXEC (Expr, globaux) code> est équivalent à
Exec Expr dans les globaux code>, tandis que le formulaire
EXEC (Expr, globaux, locaux) code> est équivalent
EXEC Expr dans les globaux locaux CODE>. La forme tuple de EXED fournit une compatibilité avec Python 3, où EXED est une fonction plutôt qu'une déclaration. P> blockQuote>
Si vous ne voulez pas l'utiliser pour une raison quelconque, voici toutes les autres options que j'ai trouvées. p>
Stubs d'importation strong> p> < P> Vous pouvez déclarer deux talons d'importation différents et importer selon l'interprète actuel. Ceci est basé sur ce que j'ai vu dans le code source Pydev. P>
Voici ce que vous mettez dans le module principal: p>
xxx pré> Voici ce que vous mettez dans < Code> exécu_python2.py code>: p>
xxx pré> voici ce que vous mettez en
exécu_python3.py code>: p>
xxx < / PRE>
EXEC dans EVAL FORT> P> NED BATCHELDER Posté une technique qui enveloppe l'instruction code> EXEC CODE> dans un appel à
eval code> de sorte qu'il ne provoquera pas d'erreur de syntaxe dans Python 3. C'est intelligent, mais pas clair. p>
xxx pré>
six package strong> p>
Six package est une bibliothèque de compatibilité pour la rédaction de code qui fonctionnera sous Python 2 et Python 3. Il a un
exécuté _ () code> fonction
qui se traduit par les deux versions. Je ne l'ai pas essayé. P> p>
Six est génial, vous devriez lui donner un coup. Fabriqué le Python 3 portant je faisais beaucoup plus facilement, et beaucoup moins de hacky (je vous regarde, "EXEC dans EVAL").
J'étais un peu hésitant à ajouter une dépendance du projet, @delnan. Incluez-vous simplement des fichiers supplémentaires dans votre projet ou une personne qui utilise votre projet doit-elle installer six aussi?
Dans mon cas, j'ai porté un outil de construction qui se démarque pour l'installation, de sorte que les dépendances étaient difficiles (bien qu'il n'y en ait, ils ne sont tout simplement pas nécessaires lors de la botte), en particulier avec six. J'ai donc fini par le regrouper en tant que sous-module, qui est autorisé et était trivial à l'exception de six.MOVES code> (nécessite un changement d'une ligne, mais je n'ai pas encore besoin de changer. ). Vous pouvez voir les changements dans leur intégralité à github.com/paver/paver/pull/82 A> (N'ayez pas peur par le grand nombre de changements, 90% de celle résultant d'un script de bootstrap Virtualenv et de supprimer et d'ajouter des bibliothèques groupées).
@Donkirkby: Vous pouvez soit déclarer six une dépendance à setup.py, ce qui signifie que toute personne qui installe votre module obtiendra automatiquement six installées (en supposant qu'ils utilisent easy_install ou PIP ou Buildout, et ils doivent). Ou vous pouvez simplement mettre le fichier SIX.PY dans votre module.
Certaines Guides de portage Python Obtenez le Si vous devez transmettre les dictionnaires globaux ou locaux, vous devrez définir une fonction personnalisée avec deux implémentations différentes, une pour Python 2 et une pour Python 3. Comme d'habitude aucune fonction personnalisée n'est nécessaire pour porter le code Python 2 dans Python 3 Strong> (*). Vous pouvez faire Python a Ainsi, p> est garanti de fonctionner de la même manière dans CPPHON 0.9.9, 1.x, 2.x, 3.x; et j'ai également vérifié que cela fonctionne dans Jython 2.5.2, PYPY 2.3.1 (Python 2.7.6) et IronPython 2.6.1: P> EXEC code>
mal fort>:
six code> comprend un excellent Mise en œuvre de cet appelé
exec _ () code>. p>
BlockQuote>
exécu (code) code>,
exécuté (code, globs) code> et
exécuté (code, globs, locs) code> dans python 2, et il travaux. P>
EXEC code> pour aussi longtemps que
exec code> existait. La raison en est que Python 2 et Python 1 (?!) Avoir un piratage pour rester compatible à l'envers em> avec Python 0.9.8 dans lequel
exécuté code> était une fonction. Maintenant, si
EXEC code> est transmis un 2 tuple, il est interprété comme
(code, globaux) code> et dans le cas d'un 3 tuple, il est interprété comme
(Code, globals, locaux) code>. Oui, le
exec _ code > dans
est inutilement compliqué. p> six code>
def print_arg(arg):
def do_print():
print(arg)
eval(compile('do_print(); print("it really works")', '<string>', 'exec'))
Ce n'est pas vrai si EXEC est dans une fonction. Vous obtenez SyntaxError: Unqualified Exec n'est pas autorisé dans la fonction "Whatevs" contient une fonction imbriquée avec des variables libres code>
@Hounshell j'ai ajouté une responsabilité de non-responsabilité. Cependant, la version originale de ma réponse indique que "aucune fonction personnalisée de ce type n'est nécessaire pour le port Python 2 B> Code dans Python 3". Ce code n'a pas fonctionné à Python 2 pour commencer; et a besoin d'une enveloppe dans Python 2 de toute façon.
Mais ne serait pas EXEC ('Imprimer "A"', {}, {}) code> jette la même exception.
Je reçois des résultats différents sur différentes machines. Je ne sais pas si c'est due à la version OS ou Python. Pastebin.com/xgcjf8mt TL; DR: Ubuntu 14.04 avec Python 2.7.6 jette une erreur, OSX 10.11.6 avec Python 2.7.10 ne le fait pas.
Mais ce n'est pas double conformément à Python3. SyntaxError: Syntaxe non valide Code> Je pense que la seule façon de faire quelque chose qui est conforme aux trois (<2.7.9,> = 2.7.9,> 3.0) est d'utiliser
eval code >. J'ai essayé ma main à cela dans une réponse séparée.
J'avais besoin de le faire, je ne pouvais pas utiliser six, et ma version de Python ne prend pas en charge la méthode de @ Antti, car je l'ai utilisé dans une fonction imbriquée avec des variables libres. Je ne voulais pas non plus d'importations inutiles. Voici ce que je suis venu avec. Cela doit probablement être dans le module, pas dans une méthode: après, ou non. Je suis un poteau Stackoverflow, pas un flic. P> mises à jour: strong> p> Pourquoi n'utilisez-vous pas simplement Ceci est démontré en essayant d'évaluer _exec code> fonctionne comme la version Python3. Vous pouvez soit remettre une chaîne, soit l'exécuter via
compile () code>. Il ne fera pas les globaux ou les locaux que vous voulez probablement, alors passez-les dans: p>
eval () code >?
eval () code> attend un em> expression em>, tandis que
exécuté () code> attend déclarations em>. Si vous venez d'obtenir une expression, cela n'a pas vraiment ce que vous utilisez car toutes les expressions valides sont des déclarations valides, mais l'inverse n'est pas vraie. Il suffit d'exécuter une méthode est une expression, même si cela ne renvoie rien; Il y a un
non implicite code> retourné. p>
PASS code>, qui est une instruction: p>
sauf, bien sûr, vous n'avez pas besoin exécu code> b> pour exécuter le code ... Vous pouvez utiliser
eval code> à la place, et ce ne serait pas être soumis à ces erreurs de syntaxe
Mais eval code> n'autorise pas plusieurs déclarations. Ceci utilise uniquement
eval code> pour terminer le
exécuté code>. C'est toujours
exécuté code> qui exécute le code. Réponse mise à jour pour démontrer un cas où
eval code> échouerait.
Voir ma réponse sur l'utilisation eval code>.
Je viens d'essayer votre do_print () code> exemple avec python 2.7 et 3.5. Ils ont tous deux fonctionné correctement avec l'intégré
EXEC () code> et imprimé 7. Pas de spécial
_EXEC () code> nécessaire. Qu'est-ce qui n'a pas fonctionné pour vous?
Antidi l'a adressée ci-dessus. Il y avait un changement de 2.7.9, j'utilisais 2.7.6
Lire le livre: Python3porting.com/Difforences.html#exec
@Lennartregebro Cette source est erronée sur
exec code>
Hein, je suis sûr que j'ai essayé ça. Va essayer à nouveau.