Chr*_*nds 10 python package python-import
用户应该通过pip安装我们的python软件包,或者可以从github存储库中克隆它并从源代码安装。import Foo出于多种原因,用户不应从源树目录中运行,例如,缺少C扩展名(numpy具有相同的问题:在此处阅读)。因此,我们想检查用户是否正在import Foo源代码树中运行,但是如何在支持Python 3和2的情况下干净,高效且可靠地执行此操作?
Edit: Note the source tree here is defined as where the code is downloaded too (e.g. via git or from the source archive) and it contrasts with the installation directory where the code is installed too.
We considered the following:
setup.py, or other file like PKG-INFO, which should only be present in the source. It’s not that elegant and checking for the presence of a file is not very cheap, given this check will happen every time someone import Foo. Also there is nothing to stop someone from putting a setup.py outside to the source tree in their lib/python3.X/site-packages/ directory or similar.setup.py for the package name, but it also adds overhead and is not that clean to parse.Foo/__init__.py during installation to note that we are now outside of the source tree.既然您numpy在评论中提到并想像他们一样做,但是没有完全理解它,我想我可以分解一下,看看您是否可以实施类似的流程。
您正在寻找的错误从这里开始,这是您在注释和答案中链接的内容,因此您已经知道这一点。它只是尝试导入,__config__.py如果不存在或无法导入,则会失败。
try:
from numpy.__config__ import show as show_config
except ImportError:
msg = """Error importing numpy: you should not try to import numpy from
its source directory; please exit the numpy source tree, and relaunch
your python interpreter from there."""
raise ImportError(msg)
Run Code Online (Sandbox Code Playgroud)
那么__config__.py文件从哪里来,这有什么帮助?让我们跟随下面...
安装该软件包后,setup将调用来运行,然后依次执行一些配置操作。从本质上讲,这就是要确保软件包已正确安装,而不是从下载目录中运行(我认为这是您要确保的内容)。
这里的关键是这一行:
config.make_config_py() # installs __config__.py
Run Code Online (Sandbox Code Playgroud)
这是导入的distutils/misc_util.py,我们可以从这里一直到这里。
def make_config_py(self,name='__config__'):
"""Generate package __config__.py file containing system_info
information used during building the package.
This file is installed to the
package installation directory.
"""
self.py_modules.append((self.name, name, generate_config_py))
Run Code Online (Sandbox Code Playgroud)
然后在此处运行该__config__.py文件,并在其中写入一些系统信息和您的show()功能。
摘要尝试
导入__config__.py失败,如果setup.py未运行,则会生成您想引发的错误,这将触发该文件的正确创建。这样不仅可以确保进行文件检查,还可以确保文件仅存在于安装目录中。在每次导入时导入一个额外的文件仍然会产生一些开销,但是无论您做什么,都首先要进行此检查会增加一些开销。
意见建议
我认为您可以numpy在完成同一件事的同时实现更轻量的版本。
删除distutils子功能,并在文件中创建选中的文件,setup.py作为标准安装的一部分。它只会在安装后存在于安装的目录中,除非用户伪造了该目录,否则它不会存在于其他目录中(在这种情况下,他们可能会解决您可能尝试的任何问题)。
作为替代方案(不知道您的应用程序和设置文件在做什么),您可能通常具有一个通常已导入的函数,该函数对于应用程序的运行不是关键,但可以使用(在numpy这种情况下,这些函数是很好的)是有关安装的信息,例如version(),而不是将这些功能放在现在放置的位置上,而是将它们制作为已创建文件的一部分,然后至少要加载要从其他位置加载的内容。
使用这种方法,您无论导入什么东西,都会带来一些开销,或者引发错误。我认为就引发错误的方法而言,因为它们不在已安装的目录中工作,这是一种非常干净直接的方法。无论使用哪种方法,使用该方法都会产生一些开销,因此我将集中精力保持开销低,简单而不会导致错误。
我不会做复杂的事情,例如解析安装文件或修改__init__.py某些地方的必要文件。我认为这些方法更容易出错是对的。
检查是否setup.py存在可以工作,但我认为它不如尝试将import其作为标准Python函数进行优化那样干净。他们完成了类似的工作,但我认为实施的numpy样式会更加直接。