【问题标题】:Differences between "import module" and "from . import module" in python?python中“import module”和“from .import module”之间的区别?
【发布时间】:2019-05-16 08:26:01
【问题描述】:

最近我发现在使用“import M”和“from .import M”时会出现奇怪的错误。我正在使用 python3.6。
例如,文档树如下。

test/
├── pacA
│   ├── a1.py
│   ├── a2.py
│   └── utils.py
├── test_a1.py
└── test_a2.py

在 utils.py 中是 func 打印机:

def printer(info):
    print(info)

在 a1.py 中是:

from .utils import printer

def pa():
    printer('printer called in a1.pa()\n')

if __name__ == '__main__':
    printer('pinter called in a1.__main__\n')

在a2.py中是:

from utils import printer

def pa():
    printer('printer called in a2.pa()\n')

if __name__ == '__main__':
    printer('pinter called in a2.__main__\n')

我们可以看到a1.py和a2.py都想在utils.py中导入打印机。他们使用不同的导入方法。这是唯一的区别。
当我从目录 pacA/ 运行 a1.py 时,我得到以下错误:

from .utils import printer
ModuleNotFoundError: No module named '__main__.utils'; '__main__' is not a package

但是运行 a2.py 会得到正确的答案。

但是,如果我使用另一个 .py 导入 a1 和 a2,事情就会好转。在test_a1.py中,代码如下:

from pacA import a1

if __name__ == '__main__':
    a1.pa()

在test_a2.py中,代码如下:

from pacA import a2

if __name__ == '__main__':
    a2.pa()

当我运行 test_a1.py 时,无论是否来自 test/,我都会得到正确的答案。但是,当我运行 test_a2.py 时,出现如下错误:

from pacA import a2
  File "/home/gph/Desktop/test/pacA/a2.py", line 1, in <module>
    from utils import printer
ModuleNotFoundError: No module named 'utils'

我应该如何在 a1 中导入 utils.py 以使这两种情况都正确?

【问题讨论】:

    标签: python python-3.x import


    【解决方案1】:

    试试这个

    pip install utils
    

    python 想让你在外部安装 utils 包

    希望对你有帮助

    【讨论】:

    • 这只是一个例子,我不想安装那个包。我只是对导入方法感到困惑。并且想知道真正发生了什么。
    • 好的,听着,我想这就是这里发生的事情?在 a1.py 中,您正在使用 .utils 导入 utils 包,这是正确的,因为 utilts 位于根目录中
    • 但在 a2.py 中并非如此,因为您尝试直接导入 utils package 。为此,utils 包必须位于 pacA 目录之外的 test 目录中
    【解决方案2】:

    我想我已经找到了这背后的原因。

    对于第一个错误,我不应该直接运行 a1.py。 当你在 a1.py 中使用相对导入 from .utils import printer 时,你不应该直接运行 a1.py。如果是这样,您将收到错误'__main__' is not a package"。要理解这一点,您需要了解if __name__==__main__ 的工作原理。

    在 a2.py 中使用from utils import printer 时,python 将搜索经典路径,包括在 sys.path 中。但是如果你运行test_a2.py,pacA是不包含的,所以我们找不到它。如果你想运行test.a2.py,那么你应该在导入utils之前包含这个sys.path.append('path to pacA')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-19
      相关资源
      最近更新 更多