[英]Python - Best practice for user-friendly way of checking for missing library dependencies?
Let's say my Python 3.6 script requires bar
in the library foo
, which it import
s at the beginning:假设我的 Python 3.6 脚本需要库foo
中的bar
,它在开头import
s :
from foo import bar
What I'd like to do is for the script to attempt the import
, and give feedback to a downstream user if foo
is not available on their system and that they should install it.我想做的是让脚本尝试import
,如果foo
在他们的系统上不可用并且他们应该安装它,则向下游用户提供反馈。
So far, I've managed to hack together this solution which is probably not very good:到目前为止,我已经设法破解了这个可能不是很好的解决方案:
try:
from foo import bar
except:
print("Need `foo` library installed")
exit(1)
I used print()
because I hope this can be a direct message to the user, but not sure if that's a good idea in the context of exception handling?我使用print()
是因为我希望这可以直接向用户发送消息,但不确定在异常处理的上下文中这是否是一个好主意?
Also, there are at least two more problems here:此外,这里至少还有两个问题:
except
clause would apply to any error that happens during import
including cases where the error is something other than the absence of foo
. except
子句适用于import
期间发生的任何错误,包括错误不是没有foo
的情况。 So this probably isn't a good use of exception handling?所以这可能不是对异常处理的好用?import
s multiple libraries, and I have to create a chunk like the above for each one!我的脚本import
了多个库,我必须为每个库创建一个像上面这样的块! I briefly considered creating a for
loop that goes through a list
of library dependencies and import
each one.我简要地考虑过创建一个遍历库依赖项list
并import
每个依赖项的for
循环。 Eg:例如:
list_of_libraries: list = ["foo", "lorem", "ipsum"]
for library in list_of_libraries:
try:
import library
except:
print("Need " + library + " library installed")
exit(1)
However, this also looks bad to me because:但是,这对我来说也很糟糕,因为:
import
s the whole library每次循环迭代都import
整个库import
takes a string
?它会失败,因为我不认为import
需要一个string
?Am I stupidly missing something here?我在这里愚蠢地错过了什么吗? What's a good way to implement this?什么是实现这个的好方法? Thank you.谢谢你。
EDIT: There are existing answers such as this one which discusses how to list dependencies in requirements.txt
and installing them with pip
.编辑:有现有的答案,例如讨论如何在requirements.txt
中列出依赖项并使用pip
安装它们的答案。 However, my question is focused on solutions I can implement inside my Python script to catch missing libraries and prompting the user to install them .但是,我的问题集中在我可以在 Python 脚本中实现的解决方案上,以捕获丢失的库并提示用户安装它们。
You can catch ModuleNotFoundError
(exists as of Python 3.6) or ImportError
(for all Python versions) to restrict your except
clause to cases of import troubles.您可以捕获ModuleNotFoundError
(自 Python 3.6 起存在)或ImportError
(适用于所有 Python 版本)以将您的except
子句限制为导入问题的情况。 ModuleNotFoundError
is a subclass of ImportError
, so catching ImportError
will work in all versions of Python. ModuleNotFoundError
是ImportError
的子类,因此捕获ImportError
将适用于 Python 的所有版本。
Errors in standard linux applications would be written to stderr instead of stdout.标准 linux 应用程序中的错误将写入 stderr 而不是 stdout。 So instead of using plain print
, you would do as follows:因此,您可以执行以下操作,而不是使用普通的print
:
import sys
try:
from foo import bar
except ImportError:
print("Need `foo` library installed", file=sys.stderr)
exit(1)
You can test it by redirecting stdout to /dev/null
.您可以通过将 stdout 重定向到/dev/null
来测试它。 You will still see the error message:您仍然会看到错误消息:
$ python foobar.py >> /dev/null
Need `foo` library installed
As for a better method than writing each import individually or looping over the required libraries, I unfortunately do not know.至于比单独编写每个导入或循环所需库更好的方法,不幸的是我不知道。 I have seen the try except ImportError
pattern been used for compatibility between modules that were renamed from Python 2 to Python 3. So for individual libraries it seems to be normal, but I have not seen anybody mass check imports.我已经看到try except ImportError
用于从 Python 2 重命名为 Python 3 的模块之间的兼容性。所以对于单个库来说,这似乎是正常的,但我没有看到任何人批量检查导入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.