.└── pkg ├── A.py ├── B.py ├── C.py ├── __init__.py └── test └── script.py
其中script.py包含:
import pkg.Bimport pkg.Aprint pkg.A.test()
A.py:
import pkg.Cdef 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更改为只导入pkg,只要在script.py中导入pkg.B,也可以正常工作.
如果我从script.py注释掉pkg.B的导入,那么如果我在A.py中导入pkg或导入pkg.C它没有什么区别,我收到一个错误:
Traceback (most recent call last): file "pkg/test/script.py",line 10,in test return pkg.B.test()AttributeError: 'module' object has no attribute 'B'
这是我期望的行为.
所以基本的问题是,为什么pkg.B.test()可以在A.py中访问,如果pkg.B没有在那里导入,如果在script.py中导入了pkg.B而且A.py导入了其他子模块?
关于这里工作的确切机制我还有点不清楚.对于描述导入逻辑的好文章的解释或指示将是最受欢迎的.
解决方法 这个问题有点陈旧,但在遇到类似问题时我偶然发现了它.这就是我所理解的情况:模块导入一次
我们首先需要了解的是,modules are loaded only once!这意味着,例如,如果我们有:
X.py:
import Zimport Yblah blah
Y.py:
import Zblah bloo
运行X.py将为我们提供以下内容:
>模块Z将在第一行加载.
>将运行模块Y(作为导入Y的结果).
>虽然导入Z是模块Y中的第一行,但模块Z是
没有再加载.
注意:无论如何,无论是否加载模块,模块的名称都会导入到当前名称空间中,使其可访问但它们都引用相同的模块对象!!
导入子模块
导入子模块(例如pkg.A)时,实际上是在加载包pkg __init__.py模块,另外还要加载A.py模块.但是你正在做的是将子模块作为属性添加到包的模块中.即:
>>> import pkg>>> hasattr(pkg,'A')False
重新启动Python会话后:
>>> import pkg.A>>> hasattr(pkg,'A')True
把碎片放在一起
因此,在执行导入pkg.B时的script.py中,将加载pkg模块,并将属性B添加到其“模块对象”中.当A.py导入pkg.C时,pkg没有加载,因为它已经加载了,而是将名称pkg导入到A.py的命名空间中,同时引用在script.py中导入的同一模块对象.因为属性B已添加到该对象(在script.py中),pkg.B.test成功,即使它在A.py中执行也是如此.
总结以上是内存溢出为你收集整理的Python包导入混乱全部内容,希望文章能够帮你解决Python包导入混乱所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)