python == python2 OU python == python3? Comment empaqueter, distribuer des scripts python py2k?

10

Selon le système, python== python2ou python== python3.

Scripts Python exécutables, commence par:

#!/usr/bin/env python
#!/usr/bin/env python2
#!/usr/bin/env python3...

Pour python py3k, il est fourni dans la documentation que je devrais / peux utiliser avec le numéro de version , donc je fais ceci:

#!/usr/bin/env python3

Mais j'ai trouvé un problème avec les scripts py2k.

Alors que dans la documentation py2k il est écrit à l' utilisation: #! /usr/bin/env python,

sur certains * nix-es, python py3k est par défaut, donc python == python3. (Par exemple , le package python ArchLinux , ici les fichiers du package python ).

Comment empaqueter (configurer, créer) et / ou préparer des scripts python pour la distribution pour gérer cela?

Je pose des questions sur la création de progiciels pouvant être exécutés facilement par les utilisateurs (sans modifier leur environnement)

Puis - je faire la même astuce pour les scripts python py2k comme pour les scripts Py3K python et le définir comme: #!/usr/bin/env python2? Puis-je être sûr que chaque distribution python py2k contient un python2fichier, alors #!/usr/bin/env python2cela fonctionnera-t-il?

Si oui, pourquoi n'est-il pas proposé en standard, par exemple dans la documentation python py2k ?

Grzegorz Wierzowiecki
la source
4
Pour autant que je sache, vous pouvez toujours l'utiliser python2pour l'exécuter (s'il est installé), et vous pouvez toujours vérifier la version avec python -V. si vous voulez que pythonce soit 2 ou 3, vous devriez rm /usr/bin/pythonpuis créer un lien symbolique qui pointe à partir de votre version python desierd par exemple ln -s /usr/bin/python2.5 /usr/bin/python.
Hanan N.
Merci de m'avoir assuré python2. Je me demande pourquoi il n'est pas standard de l'utiliser quand il y a py2k et py3k et que la valeur par défaut pythonpeut différer. Qu'en est-il de vos conseils sur le retrait - ce n'est pas approprié à cet exemple, car je pose des questions sur l'emballage. Je voudrais créer un package pouvant fonctionner dans différentes configurations / systèmes. Aucun moyen de modifier l'environnement. Qu'en est-il de la vérification - cela ne s'applique pas à Shebang - pour autant que je sache.
Grzegorz Wierzowiecki
Je crois que @Hanan N. essaie de vous dire que si vous écrivez du code Python 2.x, puis utilisez-le #!...python2dans vos programmes et si vous utilisez Python 3.x, puis utilisez #!...python3. Ne comptez pas sur le système d'exploitation pour avoir le bon lien si vous savez qu'il ne fonctionnera que sur une version spécifique. Je travaille avec des systèmes sur lesquels Python 1.5.2 est toujours installé /usr/bin/python- j'écris du code pour gérer les anciennes versions de Python ou j'utilise python2.
Arcege
2
@Arcege Je n'ai pas d' python2exécutable sur mon système (Debian squeeze). pythonest un lien symbolique vers python2.6, et python3est un lien symbolique vers python3.1, mais il n'y a pas python2.
Gilles 'SO- arrête d'être méchant'

Réponses:

3

Un script peut vérifier sa version Python et, s'il s'agit de Python 3, se redémarrer à l'aide de Python 2. Ajoutez ce qui suit près de la tête du script:

if sys.version > '3':
  python2 = os.popen('which python2 2> /dev/null').read().rstrip()
  if python2:
    args = sys.argv[:]
    args.insert(0,python2)
    os.execv(python2,args)
  else:
    sys.exit("%s requires Python Version 2 (python2 not in PATH)" % os.path.basename(__file__))

Cela utilise la whichcommande du système pour localiser python2dans l'environnement PATH. Il se relance ensuite avec cela (ou s'interrompt s'il est incapable de le trouver).

Notez que le script doit être une syntaxe Python 3 valide pour qu'il démarre dans Python 3.

De plus, toute sortie doit être vidée avant l' execvappel, sinon elle sera perdue. L'ajout, par exemple, sys.stdout.flush()juste avant l'appel à execvvidera toutes les printinstructions.

étoilé
la source
1

Sur les anciennes versions, il peut juste être au pythonlieu de python2. Pour rendre votre ligne de sheebang plus claire, vous pouvez créer un lien python2 -> pythonque vous pouvez utiliser #!/usr/bin/env python2.

DocSalvager
la source
Cependant, cela ne résout pas le problème posé. Parce que la question est de savoir comment rendre votre script suffisamment portable, afin qu'il puisse s'exécuter dans tous les environnements mentionnés (avec "python" "python2", etc.)
Grzegorz Wierzowiecki
1

Je pense que le "standard" est défini dans https://www.python.org/dev/peps/pep-0394/

Ce PEP fournit une convention pour garantir que les scripts Python peuvent continuer à être portables sur les systèmes * nix, quelle que soit la version par défaut de l'interpréteur Python (c'est-à-dire la version invoquée par la commande python).

  • python2 fera référence à une version de Python 2.x.
  • python3 fera référence à une version de Python 3.x.
  • pour le moment, toutes les distributions devraient garantir que python se réfère à la même cible que python2.
  • cependant, les utilisateurs finaux doivent savoir que python fait référence à python3 sur au moins Arch Linux (ce changement est ce qui a incité à la création de ce PEP), donc python ne doit être utilisé dans la ligne shebang que pour les scripts compatibles avec Python 2 et 3.
  • en prévision d'un éventuel changement dans la version par défaut de Python, seuls les scripts Python 2 doivent être mis à jour pour être compatibles avec Python 3 ou bien pour utiliser python2 dans la ligne shebang.
StrongBad
la source