Я хочу, чтобы мой скрипт на Python определял версию и корректно завершал работу в случае несоответствия - PullRequest
4 голосов
/ 03 марта 2010

Я хотел бы сделать это как можно более общим - например, обрабатывать как можно больше версий.

Поскольку версия 3 не имеет обратной совместимости с версией 2, я хочу убедиться, что я использую правильное выражение для печати. ​​

Пожалуйста, дайте мне знать, если у вас есть вопросы, и не стесняйтесь поделиться связанными знаниями, касающимися динамической логики, на основе того, что (например, библиотеки) доступно.

Предположим, у меня есть скрипт, который будет работать под версией 1.x, или 2.x, или только 3.x.

Или скрипт, для которого требуется библиотека A или библиотека B.

Спасибо!

EDIT:

Теперь ... когда дело доходит до Python (в отличие от .Net), некоторые библиотеки, такие как SciPy, Google App Engine держит вас привязанным к определенной версии. В Linux, Mac OS вы можете переключаться между различными установками Python из командной строки. Вот почему я хочу избежать путаницы - я хочу вспомнить, какой скрипт предназначен для какой версии Python и какие библиотеки ему нужны. Я бы предпочел, чтобы он потерпел неудачу понятным человеку образом.

Ответы [ 6 ]

8 голосов
/ 03 марта 2010

Модуль sys также содержит информацию о версии (впервые доступна в версии 2.0):

import sys

if sys.version_info[0] == 2:
    print("You are using Python 2.x")
elif sys.version_info[0] == 3:
    print("You are using Python 3.x")
7 голосов
/ 03 марта 2010

Чтобы обойти синтаксические ошибки, вам придется использовать условный импорт, если вы хотите смешать синтаксис между версиями 2 и 3.

# just psuedocode
if version is x:
   import lib_x # contains version x implementation
else:
   import lib_y # contains version y compatible implementation

Не рекомендуется пытаться поддерживать совместимость между python3 и более старыми версиями. Тем не менее, вот несколько способов определения используемой версии python:

Несмотря на то, что sys.hexversion не особенно удобен для человека, он будет работать с самыми разными версиями Python, поскольку он был добавлен еще в версии 1.5.2:

import sys
if sys.hexversion == 0x20505f0:
    print "It's version 2.5.5!"

Вы должны быть в состоянии получить информацию о версии от sys.version_info (добавлено в python 2.0):

import sys
if sys.version_info[0] == 2:
    print "You are using version 2!"
else:
    print "You are using version 1, because you would get SyntaxErrors if you were using 3!"

В качестве альтернативы вы можете использовать модуль платформы, хотя он был представлен в python 2.3 и не будет доступен в более старых версиях (при условии, что вы даже заботитесь о них):

try:
    import platform
    if platform.python_version().startswith('2'):
        print "You're using python 2.x!"
except ImportError, e:
    print "You're using something older than 2.3. Yuck."
3 голосов
/ 03 марта 2010
  • Если вы хотите поддерживать кодовую базу, которая работает с Python 2 и 3, вы бы не пытались создавать код, который будет работать в обоих, который будет неудобным, уродливым и ошибочным, вы должны написать в Python 2 и использовать 2to3 для преобразования. (Вы также можете написать в Python 3 и использовать 3to2 для преобразования, но я считаю, что инструмент менее развит.) 2to3 не совершенен, но создание кода Python 2, который может быть преобразован им, имеет гораздо больший смысл, чем создание Код Python 2, который будет работать в интерпретаторе Python 3. Редактировать: Это было распространено в 2010 году, но оказалось, что это не так. Что нужно сделать, это написать полиглот. 2to3 не стал таким полезным

  • Другой вариант - Cython , Python-подобный язык, который можно использовать для создания модулей расширения C. Модули Cython могут использоваться с Python 2 и 3.

  • Когда вы поддерживаете несколько версий Python, обычно лучше напрямую проверять наличие нужной вам возможности, чем проверять номер версии. Проверка номеров версий напрямую хрупка и косвенна.

    Например, если бы я хотел код, который будет работать с Python до 2.5, я бы сказал:

    try: 
        any
    except NameError:
        def any(iterable):
            for item in iterable:
                if item:
                    return True
            return False
    

    (учтите, что это единственная причина поймать NameError). Аналогичным образом, доступность библиотеки будет проверена с помощью команды ImportError. Редактировать: К настоящему времени существует множество инструментов для абстрагирования.

  • Если вы хотите, чтобы скрипт помнил, из какой он версии, как вы говорите, не пытайтесь вообще поддерживать несколько версий. Поместите правильный двоичный номер версии в строку shebang и запустите сценарий на основе этого.

3 голосов
/ 03 марта 2010

Если единственная проблема заключается в том, что вы хотите использовать правильный оператор печати, чтобы избежать синтаксических ошибок, вы можете полностью избежать этой проблемы, используя функцию print() в Python 2.6:

if sys.version_info[0:2] == (2,6):           # Or you could use try/except here
    from __future__ import print_function
print("Now you can use print as a function regardless of whether you're on 2.6 or 3.x!")

Конечно, если вы также хотите поддерживать более ранние версии Python, это не сработает.

2 голосов
/ 03 марта 2010

В Linux, Mac и т. Д. Вы должны использовать стандартную первую строку:

#!/usr/bin/env python2

или

#!/usr/bin/env python2.6

или

#!/usr/bin/env python3

В Windows наличие такой первой строки полезно с точки зрения документации, даже если Windows не использует ее для выбора интерпретатора.

2 голосов
/ 03 марта 2010

К вашему сведению, если вы когда-нибудь захотите перенести сценарии 2.x на 3.x, вы можете использовать 2to3 инструмент преобразования источника .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...