【问题标题】:Importing custom module cleanly干净地导入自定义模块
【发布时间】:2017-08-19 16:53:23
【问题描述】:

我想从我的子模块导入一个类,而不必使用from submodule.submodule import Class 语法。相反,我只想像普通的 Python3 模块一样做from submodule import Class

我觉得这个问题应该已经被回答了一百万次了,虽然关于 SO 有几个类似名称的问题,但没有一个通过简单的示例提供一个清晰、简单的解决方案。

我正在尝试使用此设置进行最简单的测试:

.
├── main.py
└── test
    ├── __init__.py
    └── test.py

在我的test 模块中,我有以下内容:

test.py

class Test:
    def __init__(self):
        print('hello')

__init__.py

from test import Test
__all__ = ['Test']

在上层 ma​​in.py 我有以下内容:

from test import Test
Test()

当我尝试运行 main.py 时,我得到:

ImportError: cannot import name 'Test'

我知道我可以用from test.test import Test 替换main.py 中的导入语句,但我的理解是__init__.py 的要点之一是使子模块可以在包级别访问(__all__ 允许导入都是from test import *)

【问题讨论】:

    标签: python-3.x


    【解决方案1】:

    根据PEP 404

    在 Python 3 中,包内的隐式相对导入不再是 可用 - 只有绝对导入和显式相对导入 支持的。此外,星型导入(例如 from x import *)仅 在模块级代码中允许。

    如果您将__init__.py 更改为:

    from test.test import Test
    __all__ = ['Test']
    

    那么你的代码就可以工作了:

    $ python3 main.py
    hello
    

    但现在它只适用于python3(而您的原始代码只适用于python2)。
    为了让代码在 python 的两行上都能工作,我们必须使用 explicit relative import

    from .test import Test
    __all__ = ['Test']
    

    代码执行:

    $ python2 main.py 
    hello
    $ python3 main.py 
    hello
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多