在一个项目中,一个模块 moduleA
需要访问模块 moduleB
在同一子包内 packageA
(这是在包里的 project
).该访问失败,当 __init__.py
子包的 packageA
充满了 import .. as ..
声明,而 __init__py
的包项目是空的。
为什么一个充满了 __init__.py
(似乎)阻止从这个(相同的包)模块的访问--而PyCharm似乎仍然接受它,从自动完成和高亮的角度来看? 抛出的 AttributeError
这表明 import .. as ..
语句使解释者认为子包是一个属性,而不是一个包--尽管有一个现有的 __init__.py
.
文件结构
├── ProjectA
│ ├── src
│ │ ├── project
│ │ │ ├── __init__.py
│ │ │ ├── packageA
│ │ │ │ ├── __init__.py
│ │ │ │ ├── moduleA.py
│ │ │ │ ├── moduleB.py
代码示例1
# ProjectA / src / project / __init__.py
(empty)
# packageA / __init__.py
(empty)
# packageA / moduleA.py
import project.packageA.moduleB as dummy
class A:
pass
class B:
pass
# packageA / moduleB.py
def method():
pass
代码执行1
# jupyter stated in 'C:\\Users\\username\\Desktop\\devenv\\'
# notebook located in 'C:\\Users\\username\\Desktop\\devenv\\dev\\'
import sys
sys.path
# output:
# ['C:\\src\\ProjectA',
# 'C:\\src\\ProjectA\\src',
# 'C:\\Users\\username\\Desktop\\devenv\\dev',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv\\python36.zip',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv\\DLLs',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv\\lib',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv',
# '',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv\\lib\\site-packages',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv\\lib\\site-packages\\win32',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv\\lib\\site-packages\\win32\\lib',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv\\lib\\site-packages\\Pythonwin',
# 'C:\\ProgramData\\Anaconda3\\envs\\myenv\\lib\\site-packages\\IPython\\extensions',
# 'C:\\Users\\username\\.ipython']
from project.packageA.moduleA import A, B
# no error(s)
代码示例2
第一个备选填充物 packageA / __init__.py
# packageA / __init__.py
from .moduleA import A, B
import .moduleB as dummy
第二种填充方式 packageA / __init__.py
# packageA / __init__.py
from project.packageA.moduleA import A, B
import project.packageA.moduleB as dummy
代码执行 2
from project.packageA.moduleA import A, B
AttributeError Traceback (most recent call last)
<ipython-input-1-61a791f79421> in <module>
----> 1 import project.packageA.moduleA.moduleB
C:\src\ProjectA\src\project\packageA\__init__.py in <module>
----> 1 from .moduleA import A, B
2 from .moduleB import *
C:\src\ProjectA\src\project\packageA\moduleA.py in <module>
---> 1 import project.packageA.moduleB as dummy
2
3 class A:
AttributeError: module 'project' has no attribute 'packageA'
我已经找到了解决办法 堆栈溢出。进口 __init__.py
和 import as
声明
更改导入 packageA / __init__.py
从 import .. as
到 from xx import .. as
做到了。
# packageA / __init__.py
from project.packageA.moduleA import A, B
from project.packageA import moduleB as dummy
有谁能帮我理解一下,为什么导入xx为和从xx导入xx为的工作方式不同,当涉及到子包时 -- 特别是在这种情况下,包的... __init__.py
是空的,但子包的 __init__.py
被填满?
这种行为实际上不能用任何后端机制的特征来描述:这种行为与任何文档都不匹配,例如 PEP 0221. 因此 import .. as ..
语句是无效的.这个错误似乎已经通过使用 Python 3.7 (我一直在运行3.69)