【问题标题】:Python advanced import issuePython 高级导入问题
【发布时间】:2014-11-15 13:28:20
【问题描述】:

我正在尝试制作我的第一个高级 python 项目,但我在导入方面苦苦挣扎了很长时间。

有人能描述一下python中导入的用法吗?在官方页面中找到的有关 python 导入的文档对我来说还不够...

这是一个例子:

我有以下源码结构:

$ ls -ltrR
.:
total 1
drwx------+ 1 Administrators None  0 Nov 15 14:09 b
-rwx------+ 1 Administrators None 24 Nov 15 14:10 a.py

./b:
total 6
-rwx------+ 1 Administrators None  0 Nov 15 14:08 c.py
-rwx------+ 1 Administrators None 16 Nov 15 14:10 __init__.py
drwx------+ 1 Administrators None  0 Nov 15 14:10 __pycache__
-rwx------+ 1 Administrators None 61 Nov 15 14:10 b.py

以及文件的内容:

$ cat a.py
import b

b.B().printC()

$ cat b/b.py
import c

class B:
  def printC(self):
    print(c.C().get())

$ cat b/c.py
class C():
  def get(self):
    return 'This is C'

$ cat __init__.py
from .b import *

当我启动 a.py 时,它会显示:ImportError: No module named 'c'。 当我启动 b.py 时,它只说一切都很好。

在 b.py 中我将导入修改为“import b.c”时的另一个解决方案 -> 在这种情况下,当我调用 a.py 时它会起作用,但是当我只调用 b.py 时它不会起作用因为 b.py 不知道 b 包。

为什么我还需要启动 a.py 和 b.py? a.py 应该是 UT 的 executor,b.py 应该是 UT。 这就是为什么我想调用所有的 UT 并启动 a.py,也可能发生我只是启动一个特定的 UT (b.py)。

【问题讨论】:

    标签: python import


    【解决方案1】:

    在您的 a.py 中,不要只使用 import b,而是尝试使用 from b import b,因为您想从 b 模块导入 b.py。 或者,在您的 b/init.py 中,有 from b import * 但这是一个偏好问题(有关此主题的更多信息,请查看 this thread

    This 是一个很好的模块和包入门教程。 (对于 Python 2)

    如果您使用的是 Python 3,那么情况会有些不同。 Python 3 不再支持隐式包名导入。 This link 很好地解释了这一点。因此,您需要通过使用相对导入来明确提及包的实际来源 - from . import c 而不是 import c(在您的 b.py 中)和在 a.py 中:from b import b 而不是 import b

    我们避免在 a.py 中使用相对导入,因为我们想将它作为脚本运行。在 Python 3 中,只需运行一个使用相对导入的模块,作为脚本就会抛出错误:SystemError: Parent module '' not loaded, cannot perform relative importThis link 解释了这个问题并提供了解决方案。如果您想像独立脚本一样执行模块,可以使用 -m 标志:check the docs

    所以,在你的情况下:

    a.py:

    from b import b
    
    b.B().printC()
    

    b.py:

    from . import c
    
    class B:
        def printC(self):
            print(c.C().get())
    

    c.py:没有变化 为了查找效率,最好只明确引用您真正需要导入的模块/类/函数,而不是导入整个模块。但是,如果您真的想使用 import b 导入整个“b”包,而不是使用 from b import b 从 b 包中导入 b.py 模块,则需要包含所有要发送的模块在 b/init.py 的 all 变量中,如下所示:

    __all__ = ['b', 'c']
    from . import *
    

    正如this post 中很好解释的那样。

    希望这是有用的。

    【讨论】:

    • from b import b 是不够的,因为 b 文件夹是一个包含很多 UT 的文件夹,我不想一一列出 UT。顺便说一句,我尝试了你的建议,但不行,错误是一样的。 from b import * 仍然不行。 ...谢谢你的啧啧我会检查他们
    • 我运行了你的代码,它运行良好。您使用的是哪个版本的 Python?
    • $ python --version Python 3.3.2(也许我做错了什么,你能分享你的代码吗?)
    • 我将尝试使用您的版本的代码。我尝试使用 2.7.3
    • 它对我有用,因为 Python 2 支持从包中隐式导入。 Python 3 没有。我已经编辑了答案以反映这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多