python == python2 LUB python == python3? Jak pakować, dystrybuować skrypty py2k Pythona?

10

W zależności od systemu python== python2lub python== python3.

Wykonalne skrypty Pythona, zaczynają się od:

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

W przypadku python py3k jest to zawarte w dokumentacji, której powinienem / mogę używać z numerem wersji , więc robię to:

#!/usr/bin/env python3

Ale znalazłem problem ze skryptami py2k.

Podczas gdy w py2k dokumentacji jest napisane do użytku: #! /usr/bin/env python,

na niektórych * nix-es python py3k jest domyślny, więc python == python3. (Na przykład pakiet Python ArchLinux , tutaj pliki pakietu Python ).

Jak spakować (skonfigurować, wykonać) i / lub przygotować skrypty Pythona do dystrybucji, aby sobie z tym poradzić?

Pytam o tworzenie pakietów oprogramowania, które mogą być łatwo uruchamiane przez użytkowników (bez modyfikowania środowiska)

Mogę zrobić tę samą sztuczkę dla skryptów Pythona py2k jako skrypty python py3k i ustawić go jako: #!/usr/bin/env python2? Czy mogę mieć pewność, że każda dystrybucja py2k w Pythonie zawiera python2plik, więc #!/usr/bin/env python2będzie działać?

Jeśli tak, dlaczego nie jest proponowany jako standard, na przykład w dokumentacji Python py2k ?

Grzegorz Wierzowiecki
źródło
4
O ile wiem, zawsze możesz użyć go python2do uruchomienia (jeśli jest zainstalowany) i zawsze możesz sprawdzić wersję za pomocą python -V. jeśli chcesz, że pythonbędzie to 2 lub 3, powinieneś, rm /usr/bin/pythona następnie utworzyć dowiązanie symboliczne, które wskazuje z twojej żądanej wersji Pythona np ln -s /usr/bin/python2.5 /usr/bin/python.
Hanan N.,
Dzięki za zapewnienie mi o python2. Zastanawiam się, dlaczego nie jest standardem używać go, gdy jest py2k i py3k, a domyślne pythonmogą się różnić. Co z twoją radą na temat usuwania - to nie jest właściwe dla tego przykładu, ponieważ pytam o opakowanie. Chciałbym stworzyć pakiet, który może działać w różnych konfiguracjach / systemach. Nie ma mowy o modyfikacji środowiska. A co z sprawdzaniem - nie dotyczy Shebang - o ile wiem.
Grzegorz Wierzowiecki,
Uważam, że @ Hanan N. próbuje ci powiedzieć, że jeśli piszesz kod Python 2.x, użyj go #!...python2w swoich programach, a jeśli używasz Python 3.x, użyj #!...python3. Nie polegaj na systemie operacyjnym, aby mieć odpowiedni link, jeśli wiesz, że będzie działał tylko w określonej wersji. Pracuję z systemami, które wciąż mają zainstalowany Python 1.5.2 jako /usr/bin/python- Piszę kod do obsługi starszych wersji Pythona lub używam go python2.
Arcege,
2
@Arcege Nie mam python2pliku wykonywalnego w moim systemie (ściśnięcie Debiana). pythonjest dowiązaniem symbolicznym do python2.6i python3jest dowiązaniem symbolicznym do python3.1, ale nie ma python2.
Gilles „SO- przestań być zły”

Odpowiedzi:

3

Skrypt może sprawdzić swoją wersję w języku Python, a jeśli jest to język Python 3, uruchom go ponownie przy użyciu języka Python 2. Dodaj następujące polecenie w pobliżu nagłówka skryptu:

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__))

Używa polecenia systemu whichdo zlokalizowania python2w środowisku PATH. Następnie uruchamia się ponownie z tym (lub przerywa, jeśli nie można go znaleźć).

Zauważ, że skrypt musi mieć poprawną składnię w języku Python 3, aby mógł się uruchomić w języku Python 3.

Ponadto każde wyjście powinno zostać opróżnione przed execvpołączeniem, w przeciwnym razie zostanie utracone. Dodanie na przykład sys.stdout.flush()tuż przed wywołaniem execvspowoduje opróżnienie wszystkich printinstrukcji.

rozgwiazdy
źródło
1

W starszych wersjach może po prostu być pythonzamiast python2. Aby Twoja linia sheebang była wyraźniejsza, możesz utworzyć link python2 -> python, abyś mógł z niej korzystać #!/usr/bin/env python2.

DocSalvager
źródło
Nie rozwiązuje to jednak stwierdzonego problemu. Ponieważ pytanie brzmi, jak uczynić skrypt wystarczająco przenośnym, aby mógł działać we wszystkich wymienionych środowiskach (z „python” „python2” itp.)
Grzegorz Wierzowiecki,
1

Myślę, że „standard” jest zdefiniowany w https://www.python.org/dev/peps/pep-0394/

Ten PEP zapewnia konwencję zapewniającą, że skrypty Pythona mogą być nadal przenośne w systemach * nix, niezależnie od domyślnej wersji interpretera Pythona (tj. Wersji wywoływanej przez komendę python).

  • Python2 będzie odnosił się do niektórych wersji Python 2.x.
  • Python3 będzie odnosił się do niektórych wersji Python 3.x.
  • na razie wszystkie dystrybucje powinny zapewnić, że python odnosi się do tego samego celu co python2.
  • użytkownicy końcowi powinni jednak pamiętać, że python odnosi się do python3 przynajmniej na Arch Linux (ta zmiana spowodowała utworzenie tego PEP), więc python powinien być używany w wierszu shebang tylko dla skryptów, które są kompatybilne ze źródłami z Python 2 i 3.
  • w ramach przygotowań do ewentualnej zmiany domyślnej wersji języka Python, skrypty tylko w języku Python 2 powinny zostać zaktualizowane, aby były zgodne ze źródłami języka Python 3, lub też w celu użycia python2 w linii shebang.
StrongBad
źródło