在Python 3.7中创建包和导入子模块

2024-04-26 09:34:02 发布

您现在位置:Python中文网/ 问答频道 /正文

Python 3.7中的以下结构不允许我在模块B中导入类A

Test:
    test:
        __init__.py
        a:
            __init__.py
            a.py
        b:
            __init__.py
            b.py

顶层__init__为空。以下是剩余的文件:

a

#__init__.py
from .a import A
#a.py
class A:

    def __init__(self,
                 *args,
                 **kwargs):
        '''
        '''
        pass

b

#__init__.py
from .b import B
#a.py
from test.a import A

class B:

    def __init__(self,
                 *args,
                 **kwargs):
        '''
        '''
        pass

在Windows上,如果我尝试运行b.py,而不执行任何其他操作,则会出现以下错误:

ModuleNotFoundError: No module named 'test.a'

有人能解释一下我为什么会犯这个错误吗?我也看到过一些类似的帖子,但它们并没有解决我的问题:

  1. Importing Submodules Python 3
  2. Python submodule importing correctly in python 3.7 but not 3.6

Tags: 模块frompytestimportselfinitdef
1条回答
网友
1楼 · 发布于 2024-04-26 09:34:02

setuptools是从项目创建包所必需的。发展的最佳做法是:

  1. 创建虚拟环境(请参见pipenv
  2. 在项目中创建每个文件夹。每个带有__init__.py的文件夹都成为一个包
  3. 在顶层之外创建一个setup.py(使用setuptools
  4. 从顶级软件包外部运行pipenv install -e .以安装*

*注意这个-e代表“可编辑”。开发时,它会在代码的python安装中放置一个链接(*.pth文件),以便安装包,但任何更改都会立即生效(请参见Python Packaging Tutorial)。这样,您的所有测试代码、客户机代码等都可以以通常的方式导入您的包

对于上述示例,目录修改为以下内容:

Test
+  test/
|  +  __init__.py
|  +  a/
|  |  +  __init__.py
|  |  +  a.py
|  +  b/
|  |  +  __init__.py
|  |  +  b.py
+  setup.py

setup.py如下所示:

#setup.py
from setuptools import (
    setup,
    find_packages
)

setup(
    name = 'test-your_username',
    version = '0.0.1', # look at semantic versioning 2.0
    python_requires = '>=3.7', # assuming you want Python 3.7 or greater
    packages = find_packages(),
)

要运行的完整命令行指令如下:

C:\Users\username\Documents\Test> pipenv  three
C:\Users\username\Documents\Test> pipenv shell
(test-#####) C:\Users\username\Documents\Test> pipenv install .

如果随后从虚拟环境中运行python,则可以导入包结构:

(test-#####) C:\Users\username\Documents\Test>py
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> import test.a
>>> import test.b

相关问题 更多 >