Python包导入混乱

Python包导入混乱,第1张

概述如果我有一个目录结构,如: .└── 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.Cd 如果我有一个目录结构,如:

.└── 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包导入混乱所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1197252.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存