填写的__init__似乎阻止了对同一包中模块的访问。

问题描述 投票:0回答:1

在一个项目中,一个模块 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__.pyimport as 声明

更改导入 packageA / __init__.pyimport .. asfrom 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 被填满?

python import module package init
1个回答
0
投票

这种行为实际上不能用任何后端机制的特征来描述:这种行为与任何文档都不匹配,例如 PEP 0221. 因此 import .. as .. 语句是无效的.这个错误似乎已经通过使用 Python 3.7 (我一直在运行3.69)

© www.soinside.com 2019 - 2024. All rights reserved.