在python中遇到ImportError时,我应该直接引发错误并要求用户安装它,还是应该使用import chain?
当我尝试使用lxml包来解析python中的xml文件时,我遇到了这个问题 在其官方文件中,它说:
如果您的代码仅使用ElementTree API并且不依赖于lxml.etree特有的任何功能,您还可以使用以下导入链的(任何部分)作为原始ElementTree的后备:< / p>
try:
from lxml import etree
print("running with lxml.etree")
except ImportError:
try:
import xml.etree.cElementTree as etree
print("running with cElementTree on Python 2.5+")
except ImportError:
...
在我看来,导入替换是一个坏主意,因为:
如果您可以导入另一个库作为替换,可能没有所有方法作为lxml,那么所有脚本只能基于所有包中的可用方法。
然后导入最强大的包(例如lxml)没有意义,我们可以直接导入功能最少的包,并保存很多代码。或者如果我们想稍后使用其他方法,那么我们应该直接引发ImportError。
但是,正如Error handling when importing modules 中所解释的那样,我发现这种方法似乎经常在python编程中使用:
根据运行时导入的库定义多级功能非常有用。
但在我看来,多级功能只能通过不断检查是否已导入一个库来实现,这使得整个代码变得复杂和丑陋。
结果,我只是想知道为什么人们有时会使用这种结构,而不是直接提出错误?
答案 0 :(得分:1)
首先回答你的上一个问题:
在python中遇到ImportError时,我应该直接引发错误并要求用户安装它,还是应该使用import chain?
您可以出于多种原因处理ImportError
:
现在提出其他问题:
然后导入最强大的软件包(例如lxml)不太合理,我们可以直接导入功能最少的软件包,并保存很多代码。
在lxml.etree
,ElementTree
和cElementTree
的特定情况下,这三者都实现了相同的API。他们互相替代。 ElementTree
是纯Python并且始终有效,但cElementTree
通常存在并且更快。 lxml.etree
更快,但是是一个外部模块。
这样想:
try:
import super_fast_widget as widget
except ImportError:
try:
import fast_widget as widget
except ImportError:
import slow_widget as widget
从您的代码的角度来看,widget
无论哪个库实际上最终导入都会一直运行相同,因此最好尝试导入最快的实现并重新开始如果表现是你关心的事情,那就慢了。
您是正确的,因为如果您允许回退库,则无法充分利用所有的lxml
功能。这就是使用lxml.etree
而不仅仅是lxml
的原因。它故意模仿其他两个库的API。
以下是Django代码库中的类似示例:
# Use the C (faster) implementation if possible
try:
from yaml import CSafeLoader as SafeLoader
from yaml import CSafeDumper as SafeDumper
except ImportError:
from yaml import SafeLoader, SafeDumper
Python内部为许多内置模块执行此操作。这是一个较慢的纯Python版本,可用作更快的C版本的后备版。
但是,正如在导入模块时的错误处理中所解释的那样,我发现这种方法似乎在python编程中经常使用:
您的lxml.etree
示例替换速度较慢的库以获得更快的库。链接的示例代码为一堆库提供了一个通用的跨平台接口(getpass
),这些库都做同样的事情(提示您输入密码)。作者处理ImportError
因为这些单独的模块可能不存在,具体取决于您的操作系统。
您可以使用try
和类似代码替换某些if platform.system() == 'Windows'
块,但即使在单个操作系统中,也可能有更好的模块执行相同的任务,因此try
阻止简化它。最后,getpass
仍会提示用户输入完全相同的API密码,这是您真正关心的。
答案 1 :(得分:0)
我通常使用导入链,因为输出更受控制。
提高错误
Traceback (most recent call last):
File "core.py", line 1, in <module>
ImportError: <error description>
导入链
i Importing "lxml.etree"
x Error Importing "lxml.etree"
i Importing "xml.etree.cElementTree" on Python 2.5+
x Error Importing "xml.etree.cElementTree" on Python 2.5+
i Please Install "lxml.etree" or "xml.etree.xElementTree" on Python 2.5+
i Exit with code 1