ModuleNotFoundError - Python 模块组织

ModuleNotFoundError - Python Module Organization

我正在尝试通过将源代码放在 src/ 目录下并在 tests/ 目录下进行测试来创建名为 some_module 的 python 模块。

当前 tree 结构在 some_module/ 目录中如下所示

└─[$] <git:(property_play*)> tree
.
├── __init__.py
├── src
│   ├── birds.py
│   ├── __init__.py
│   ├── mammals.py
│   └── __pycache__
│       ├── birds.cpython-36.pyc
│       └── mammals.cpython-36.pyc
└── tests
    └── import_test.py

3 directories, 7 files

我们可以看到 src/ 包含两个名为 birds.pymammals.py

的 python 文件

birds.py 的内容是

class Birds:
    def __init__(self):
        ''' Constructor for this class. '''
        # Create some member animals
        self.members = ['Sparrow', 'Robin', 'Duck']


        def printMembers(self):
        print('Printing members of the Birds class')
        for member in self.members:
           print('\t%s ' % member)

mammals.py 的内容是

class Mammals:
    def __init__(self):
        ''' Constructor for this class. '''
        # Create some member animals
        self.members = ['Tiger', 'Elephant', 'Wild Cat']


    def printMembers(self):
        print('Printing members of the Mammals class')
        for member in self.members:
            print('\t%s ' % member)

最后是 import_test.py

的内容
from some_module.src.birds import Birds
from some_module.src.mammals import Mammals

# Create an object of Mammals class & call a method of it
myMammal = Mammals()
myMammal.printMembers()

# Create an object of Birds class & call a method of it
myBird = Birds()
myBird.printMembers()

现在,每当我尝试 运行 import_test.py 时,我都会收到以下错误

└─[$] <git:(property_play*)> python3 import_test.py 
Traceback (most recent call last):
  File "import_test.py", line 5, in <module>
    from some_module.src.birds import Birds
ModuleNotFoundError: No module named 'some_module'

我尝试了相对和绝对导入,但没有成功。谁能告诉我我在这里遗漏了什么?

如果有人建议以触发命令 dir 对导入没有影响的方式导入这些模块,那就太好了。

您模块中的组织是非标准的python。要使代码在您的情况下工作,您可能需要更改:

from some_module.src.birds import Birds
from some_module.src.mammals import Mammals

from src.birds import Birds
from src.mammals import Mammals

但是,根据您尝试从哪个文件夹 运行 您的测试,您可能需要检查或修改 sys.path.

的内容

您还可以将 $PYTHONPATH 设置为指向根目录,即 some_module 目录。

总的来说,我建议您通读 Python's import docs to get an understanding of how imports work. Or just look at a modern project like Starlette or use a complete tool for managing everything like Poetry

因为我想使用绝对 import 路径而不是相对路径,所以触发的命令 dir 应该不会对这些导入产生影响。

构建和安装我的模块是必经之路。我使用 setuptools 添加了一个小的 setup.py 来解决我的问题。

#!/usr/bin/env python3

import os
import re

from setuptools import setup


def find_packages(package):
    """
    Return root package and all sub-packages.
    """
    return [
        dirpath
        for dirpath, dirnames, filenames in os.walk(package)
        if os.path.exists(os.path.join(dirpath, "__init__.py"))
    ]


setup(
    name="some_module",
    python_requires=">=3.6",
    version="1.0.0",
    author="Shravan Kumar Gond",
    description="Module For absolute imports",
    packages=find_packages("some_module"),
    include_package_data=True,
    cmdclass={
        "package": Package
    }
    zip_safe=False,
)

现在,您可以 buildinstall 您的模块 sys.path 通过 运行 以下命令

$ python3 setup.py build
$ python3 setup.py install

现在所有的绝对 import 应该像魅力一样工作:)