如何解决Python 如何知道从我正在处理的代码中导入,而不是从站点包中导入? 背景问题
背景
我有一个正在处理的软件包,我也已将其安装到 site-packages
中。 (我已经使用 pip
安装了自己的软件包)
问题
Python 怎么知道从“本地”代码(我正在处理的代码)导入,而不是从 site-packages
导入?我问是因为 我想更好地理解,我担心当我真的想使用我自己的(最新)代码时,我可能会以某种方式从 site-packages
导入代码
让我感到困惑的是,我们如何编写导入并没有更清楚。在我看来,程序员不知道她是导入自己的代码还是从 site-packages
导入。我在这里遗漏了什么吗?
我的一个想法是使用相对导入,但如果我理解它们一般不推荐
我使用的是 Python 3.8.5
解决方法
Python 的 import
机制(通常称为导入机制)基于 Finders and Loaders。当您使用 import 语句导入模块时,一系列查找器会尝试查找您正在导入的模块。你可以看到按顺序触发的所有finder的列表:
>>> import sys
>>> sys.meta_path
[<class '_frozen_importlib.BuiltinImporter'>,<class '_frozen_importlib.FrozenImporter'>,<class '_frozen_importlib_external.PathFinder'>]
如果所有发现者都无法解析模块,则引发 ModuleNotFoundError
。
BuiltinImporter
解析预加载到解释器中的模块,如 sys、time、gc 等。 FrozenImporter
解决冻结模块。 PathFinder
通过遍历 sys.path
中的路径解析模块。
打印 sys.path
显示您的当前目录是第一个条目,因此首先搜索匹配项。
这里有一个简单的序列,您可以使用它来推断导入将从哪里发生:
- 是内置模块的模块部分。示例:
import sys
。即使您的当前目录中有一个名为 sys.py 的文件,由于BuiltinImporter
首先被调用,它会解析内置的 sys 模块。 - 该模块是否存在于您的当前目录中,因为它是
sys.path
中的第一个条目。 - 该模块是否可作为核心 python 或站点包的一部分使用。
由 PathFinder 导入的模块(存在于 sys.path 中的模块)将具有 __path__
作为属性,您可以检查它的位置。
还可以在 sys.meta_path 中重新排序查找器,甚至可以添加您自己的自定义查找器和加载器,让您可以完全控制和创造性地修改默认机器。可以注册自定义查找器和加载器以查找系统中其他位置的模块,甚至可以从外部系统动态查找模块。
,如果您想将您的软件包符号链接为开发安装,请使用:
pip install --no-dependencies --editable .
或:
python setup.py develop
无需修改sys.path
您当前的文件夹将被符号链接到站点包。因此,如果
你的包名是 foo
,你可以用
from foo import bar
# or
import foo
foo.bar.do_something()
,
我会考虑创建一个virtual enviroment,它没有安装了 pip 包。这是您可以确定您使用的是本地版本!
如果您对从何处导入包感到困惑,可以使用 .__path__
去了解一下。
import my_package
print(my_pacakge.__path__)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。