您如何优雅地处理失败的未来功能导入?如果用户使用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:
在future_statement之前可以出现的唯一行是:
模块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的这个片段似乎给了内联的希望:
问:我想将future_statements包装在try/except块中,因此我可以使用不同的代码,具体取决于我正在运行的Python版本.为什么我不能?
A:对不起!try/except是一个运行时功能; future_statements主要是编译时的噱头,你的try/except在编译完成后很久就会发生.也就是说,当你尝试使用/ except时,对模块有效的语义已经完成了.由于试/除非将无法完成它看起来 像它应该做到,它只是不允许的.我们还希望保持这些特殊陈述非常容易找到和识别.
请注意,您可以直接导入__future__,并使用其中的信息以及sys.version_info来确定您正在运行的版本与给定功能的状态相关的位置.
想法?
"我想告诉用户他们需要用Python> = 2.6重新运行程序,并且可能会提供一些如何操作的说明."
这不是README文件的用途吗?
这是你的选择."包装器":在运行目标aop之前检查环境的一小块Python.
文件: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"
我之前使用的一个相当hacky但很简单的方法是利用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 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