код python 2: если python 3, то sys.exit()

У меня есть большой кусок кода только для Python 2. Он хочет проверить Python 3 в начале и выйти, если используется python3. Итак, я попытался:

import sys

if sys.version_info >= (3,0):
    print("Sorry, requires Python 2.x, not Python 3.x")
    sys.exit(1)

print "Here comes a lot of pure Python 2.x stuff ..."
### a lot of python2 code, not just print statements follows

Однако выхода не происходит. Результат:

$ python3 testing.py 
  File "testing.py", line 8
        print "Here comes a lot of pure Python 2.x stuff ..."
                                                        ^
SyntaxError: invalid syntax

Итак, похоже, что python проверяет весь код перед выполнением чего-либо, и, следовательно, ошибка.

Есть ли хороший способ для кода python2 проверить, используется ли python3, и если да, напечатать что-то дружественное, а затем выйти?


person superkoning    schedule 30.06.2012    source источник


Ответы (1)


Python будет байт-компилировать ваш исходный файл, прежде чем начать его выполнение. Весь файл должен быть как минимум правильно разобран, иначе вы получите ошибку SyntaxError.

Самое простое решение вашей проблемы — написать небольшую оболочку, которая анализирует как Python 2.x, так и 3.x. Пример:

import sys
if sys.version_info >= (3, 0):
    sys.stdout.write("Sorry, requires Python 2.x, not Python 3.x\n")
    sys.exit(1)

import the_real_thing
if __name__ == "__main__":
    the_real_thing.main()

Оператор import the_real_thing будет выполняться только после оператора if, поэтому код в этом модуле не требуется анализировать как код Python 3.x.

person Sven Marnach    schedule 30.06.2012
comment
Вы также можете использовать блок if __name__ == "foo", который работает как блок if __name__ == "__main__", но выполняется при импорте блока foo. - person inspectorG4dget; 01.07.2012
comment
Не будет ли более Pythonic использовать EAFP и просто поместить импорт the_real_thing в try блок? - person martineau; 01.07.2012
comment
@martineau: я бы не стал этого делать в данном случае. import вполне может быть успешным, а в main() могут возникнуть другие ошибки. Вы не хотите заключать the_real_thing.main() в try/except. - person Sven Marnach; 01.07.2012
comment
@ InspectorG4dget: я не очень понял ваш комментарий, но я добавил if __name__ == "__main__": для полноты картины. - person Sven Marnach; 01.07.2012
comment
@SvenMarnach: if __name__ == "__main__" — это первый блок, который выполняется при запуске foo.py. if __name__ == "foo" — это первый блок, который выполняется из foo.py, когда foo.py импортируется в bar.py. - person inspectorG4dget; 01.07.2012
comment
@ InspectorG4dget: эти блоки выполняются первыми, только если они находятся в начале файла. Наверное, я скучный, но я правда не понимаю! - person Sven Marnach; 01.07.2012
comment
@SvenMarnach: вы можете добавить такой блок в начало файла. Тогда не имело бы значения, соответствует ли остальное py3.x/поддается анализу. Мои протоколы связи, вероятно, устарели, поэтому я не могу донести до вас свою точку зрения. Вы, вероятно, не знаете этого, но я смотрю на вас уже несколько лет. Так что, пожалуйста, не говорите, что я скучный - person inspectorG4dget; 01.07.2012
comment
@ InspectorG4dget: перед тем, как Python начнет выполнять модуль, весь файл компилируется побайтно. Это включает в себя синтаксический анализ всего файла. Добавление if __name__ == "foo" ничего не меняет. - person Sven Marnach; 01.07.2012