Как изящно справиться с неудачной функцией будущего (__future__) импорта из-за старой версии интерпретатора?

Как вы грациозно обрабатываете неудачные будущие функции импорта? Если пользователь работает с Python 2.5, а первый оператор в моем модуле:

from __future__ import print_function 

Компиляция этого модуля для Python 2.5 завершится неудачно:

  File "__init__.py", line 1 from __future__ import print_function SyntaxError: future feature print_function is not defined 

Я хотел бы сообщить пользователю, что им нужно перезапустить программу с помощью Python> = 2.6 и, возможно, предоставить некоторые инструкции о том, как это сделать. Однако, чтобы указать PEP 236 :

Единственными строками, которые могут появиться перед будущим_значением, являются:

  • Модуль docstring (если есть).
  • Комментарии.
  • Пустые строки.
  • Другие future_statements.

Поэтому я не могу сделать что-то вроде:

 import __future__ if hasattr(__future__, 'print_function'): from __future__ import print_function else: raise ImportError('Python >= 2.6 is required') 

Потому что это дает:

  File "__init__.py", line 4 from __future__ import print_function SyntaxError: from __future__ imports must occur at the beginning of the file 

Этот фрагмент из PEP, похоже, дает надежду сделать это inline:

В: Я хочу обернуть будущие_статы в try / except block, поэтому я могу использовать другой код в зависимости от того, какая версия Python я запускаю. Почему я не могу?

A: Извините! try / except – это функция времени исполнения; future_statements – это прежде всего компиляционные трюки, и ваша попытка / исключение происходит слишком долго после завершения компилятора. То есть, к тому времени, когда вы пытаетесь / исключаете, семантика, действующая для модуля, уже является готовой сделкой. Поскольку try / except не выполнит то, на что похоже, что он должен выполнить, это просто не разрешено. Мы также хотим, чтобы эти специальные заявления были очень легко найти и распознать.

Обратите внимание, что вы можете напрямую импортировать __future__ и использовать информацию в нем вместе с sys.version_info, чтобы выяснить, где находится релиз, в котором вы работаете, в зависимости от статуса данной функции.

Идеи?

3 Solutions collect form web for “Как изящно справиться с неудачной функцией будущего (__future__) импорта из-за старой версии интерпретатора?”

«Я хочу сообщить пользователю, что им нужно перезапустить программу с помощью Python> = 2.6 и, возможно, предоставить некоторые инструкции о том, как это сделать».

Разве это не файл README?

Вот ваша альтернатива. «Обертка»: небольшое пятно Python, которое проверяет среду перед запуском целевого aop.

Файл: appwrapper.py

 import sys major, minor, micro, releaselevel, serial = sys.version_info if (major,minor) <= (2,5): # provide advice on getting version 2.6 or higher. sys.exit(2) import app app.main() 

Что означает «прямой импорт». Вы можете просмотреть содержимое __future__ . Вы по-прежнему связаны тем фактом, что a from __future__ import print_function – это информация для компилятора, но вы можете сориентироваться перед импортом модуля, который выполняет настоящую работу.

 import __future__, sys if hasattr(__future__, 'print_function'): # Could also check sys.version_info >= __future__. print_function.optional import app app.main() else: print "instructions for upgrading" 

Довольно хакерский, но простой метод, который я использовал ранее, заключается в том, чтобы использовать тот факт, что байтовые литералы были введены в Python 2.6 и используют что-то вроде этого в начале файла:

 b'This module needs Python 2.6 or later. Please do xxx.' 

Это безобидно в Python 2.6 или новее, но SyntaxError в любых более ранних версиях. Любой, кто пытается скомпилировать ваш файл, все равно получит ошибку, но также получит любое сообщение, которое вы хотите дать.

Вы можете подумать, что, поскольку вам придется иметь эту строку после from __future__ import print_function тогда будет импорт, который генерирует SyntaxError и вы не увидите полезное сообщение об ошибке, но, как ни странно, более поздняя ошибка имеет приоритет. Я подозреваю, что поскольку ошибка импорта не является синтаксической ошибкой сама по себе, она не возникает при первом проходе компиляции, и поэтому реальные ошибки синтаксиса возникают сначала (но я предполагаю).

Это может не соответствовать вашим критериям для того, чтобы быть «изящным», и это очень специфичный Python 2.6, но это быстро и легко сделать.

Просто "from __future__ import ..." комментарий к той же строке с "from __future__ import ..." , например:

 from __future__ import print_function, division # We require Python 2.6 or later 

Поскольку Python отображает строку, содержащую ошибку, если вы попытаетесь запустить модуль с Python 2.5, вы получите приятную описательную ошибку:

  from __future__ import print_function, division # We require Python 2.6 or later SyntaxError: future feature print_function is not defined 
  • Импорт модулей Python - Явный и неявный относительный импорт
  • Почему модули Python иногда не импортируют свои подмодули?
  • как использовать из __future__ import print_function
  • Setup.py: установить lxml с Python2.6 на CentOS
  • Импорт Python с __init__.py
  • Как сделать эквивалент «import * from module» с функцией __import__ Python?
  • Подтверждение разницы между import * и from xxx import *
  • Python, Windows и многопроцессорность
  • Python - лучший язык программирования в мире.