gpt4 book ai didi

Python包导入困惑

转载 作者:太空宇宙 更新时间:2023-11-03 11:50:28 25 4
gpt4 key购买 nike

如果我的目录结构如下:

.
└── pkg
├── A.py
├── B.py
├── C.py
├── __init__.py
└── test
└── script.py

script.py 包含:

import pkg.B
import pkg.A

print pkg.A.test()

A.py:

import pkg.C

def test():
return pkg.B.test()

B.py:

def test():
return 'AAAA'

C.py:

def test3():
return 'C.test3'

并且 __init__.py 是空的。

如果 A.py 导入 pkg.C,则代码可以工作。如果我注释掉那个导入,那么它会失败:

Traceback (most recent call last):
File "pkg/test/script.py", line 9, in <module>
print pkg.A.test()
File "/Users/X/Desktop/importtest/pkg/A.py", line 4, in test
return pkg.B.test()
NameError: global name 'pkg' is not defined

import pkg.C 更改为仅 import pkg,只要 pkg.B 被导入到 script 中,也可以正常工作。 py

如果我从 script.py 注释掉 pkg.B 的导入,那么如果我 import pkgimport pkg.C in A.py,我得到一个错误:

Traceback (most recent call last):
File "pkg/test/script.py", line 10, in <module>
print pkg.A.test()
File "/Users/X/Desktop/importtest/pkg/A.py", line 4, in test
return pkg.B.test()
AttributeError: 'module' object has no attribute 'B'

这是我期望的行为。

所以基本问题是,为什么 pkg.B.test() 可以在 A.py 中访问,如果 pkg.B 不是t 在那里导入,如果 pkg.B 导入到 script.pyA.py 导入其他子模块?

我仍然不太清楚这里的确切机制是什么。非常感谢解释或指向描述导入逻辑的好文章。

最佳答案

这个问题有点老了,但我在遇到类似问题时偶然发现了它。这就是我所了解的情况:

模块导入一次

我们首先需要了解的是,modules are loaded only once !这意味着,例如,如果我们有:

X.py :

import Z
import Y
blah blah

Y.py :

import Z
blah bloo

正在运行 X.py会给我们以下内容:

  1. 模块 Z 将在第一行加载。
  2. 模块 Y 将运行(作为 import Y 的结果)。
  3. 虽然import Z是模块中的第一行 Y , 模块 Z没有再次加载。

注意:不管一个模块是否被加载,模块的名称都是导入进入当前命名空间,使其可访问但它们都引用相同的模块对象!!

导入子模块

导入子模块时,例如 pkg.A ,您实际上是在加载包 pkg __init__.py模块,另外,加载 A.py 模块。而且您正在做的是将子模块作为属性添加到包的模块。即:

>>> import pkg
>>> hasattr(pkg, 'A')
False

重述 Python session 后:

>>> import pkg.A
>>> hasattr(pkg, 'A')
True

拼凑

所以,在 script.py什么时候import pkg.B被执行,pkg模块已加载且属性 B被添加到它的模块对象中。当A.py进口pkg.C , pkg未加载因为它已经加载,而是名称 pkg被导入 A.py的命名空间,同时引用在 script.py 中导入的同一模块对象 .因为属性 B已添加到该对象(在 script.py 中)pkg.B.test成功,即使它在 A.py 中执行.

关于Python包导入困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29286406/

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