gpt4 book ai didi

python - 为什么常规包中的 __path__[0] 是唯一搜索的索引?

转载 作者:太空宇宙 更新时间:2023-11-04 05:55:25 25 4
gpt4 key购买 nike

当我在 Python 中创建一个常规包时,我得到一个带有 __path__ 方法的对象,根据 Python 文档,它被认为是一种特殊类型的模块。我的问题是为什么在 pack.__path__ list 中只搜索第一个项目而其他项目被省略,为什么它是一个列表而不是一个普通的字符串,因为其他项目没有被扫描?

例子:假设我们有一个名为 C:\code 的目录,其中包含一个名为 pkg 的包。和另一个包含 spam.py 的路径:

    C\
pkg\ #Regular package
.__init__.py
another\
spam.py #print('spam')

>>> import pkg

>>> pkg.__path__ #Only __path__[0] searched
['C:\\code\\pkg']

>>> pkg.path.append(r'C:\another')

>>> pkg.__path__
['C:\\code\\pkg', 'C:\\another'] # __path__[1] omitted

>>> import pkg.spam # Fails!
ImportError:...

>>> pkg.__path__.pop(0) # Works!
>>> pkg.spam
spam

所以我想知道为什么 Python 只遍历 __path__[0] 而不是像在 3.X 中那样遍历命名空间包的整个列表?如果没有完全遍历,将 __path__ 作为列表是没有意义的。我知道常规包与 namespace 包不同,但为什么要在这里列出一个列表并只允许单一搜索路径呢!但是,Python 3.3 遍历了整个列表,它以某些形式通过在 __path__ 属性中为常规包添加目录来模拟命名空间包的行为。

最佳答案

__path__[0] 不仅是 Python 在包内搜索相对导入的路径。至少这是我在 Cpython 2.7 和 Python 3.3 中测试的真实行为。 Python 在使用相对导入时从左到右遍历 __path__[0]__path__[0] 列表的作用与sys.path 的作用相同。它们都包含导致包或模块的系统路径(目录前缀),Python 在使用任何 import 语句(例如 importfrom)时自动收集这些包或模块

实际上,您可以使用 pkgutil.extend_path 函数扩展 __path__[0],让相关包导入,从包目录以外的不同目录导入。例如:

C:
\dir0 #container directory
\pkg #package
__init__.py
spam.py
\dir1
ham.py
>>> __path__
['C:\\dir0']

假设__init__.py文件(初始化文件)包含以下代码:

__path__.append(r'C:\\dir1')    #Or pkgutil.extend_path function
from . import spam,ham #Relative import(relative to pkg dir)

spam 将从包的目录导入,因为这是 2.X 和 3.X 中的相对导入。但是,请注意 ham 也将如何成功导入,即使它不像 spam 模块那样位于包的主目录中,它仍然可以作为目录导入pkg 包的 __path__ 列表中的模块 ham

由于 ham 是自动导入的,没有任何错误,这表明 Python 从左到右遍历包的 __path__ 列表。

虽然,您可以将 __path__ 视为 sys.path,但 __path__ 仅用于包内的导入。Python 2.X在 sys.path 之前搜索 __path__。那是先相对后绝对。 Python 3.X 将其更改为 absolute-only,除非您在 from 导入语句 from 中使用点。 import ...,Python 3.X 会一直搜索模块搜索路径。

关于python - 为什么常规包中的 __path__[0] 是唯一搜索的索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28076999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com