首页 > 解决方案 > Python 目录地狱

问题描述

这是我的目录结构:

├── src
│   ├── helpers
│   │   ├── __init__.py
│   │   ├── foo.py
│   │   └── bar.py
│   ├── services
│   │   ├── __init__.py
│   │   ├── faz.py
│   │   └── baz.py
│   └── main.py
├── tests
│   ├── helpers
│   │   ├── test_foo.py
│   │   └── test_bar.py
│   ├── services
│   │   ├── test_faz.py
│   │   └── test_baz.py

我的src/helpers/__init__.py样子如下:

from .foo import Foo
from .bar import Bar

src/services/__init__.py看起来像:

from .faz import Faz
from .baz import Baz

我的src/main.py

import helpers

f = helpers.Foo()

我的tests/helpers/test_foo.py

import src.helpers as helpers

def test_foo():
    f = helpers.Foo()

所有这些都有效

但是,在我的问题中,比如说,src\services\faz.py references src\helpers\foo.py是什么时候。

目前,...\faz.py如下所示:

import helpers

class Faz():
   def DoSomething(self):
      # something

如果我运行,这将有效python src/main.py。但如果我运行coverage run -m pytest,我会得到错误ModuleNotFoundError: No module named 'helpers'。如果我将 import 语句更改为import src.helpers,则测试有效,但应用程序不再有效。

我该如何解决?

谢谢!

标签: python

解决方案


我认为你需要把它变成一个可安装的 python 包。您只需执行普通的 python 包导入,而不是破解路径。假设该产品名为“foopackage”,您可以添加 src/foopackage 并包含 setup.py 文件。

├── src
│   ├── foopackage
│   │   ├── helpers
│   │   │   ├── __init__.py
│   │   │   ├── foo.py
│   │   │   └── bar.py
│   │   └── services
│   │       ├── __init__.py
│   │       ├── faz.py
│   │       └── baz.py
│   └── scripts
│       └── main.py
├── tests
│   ├── helpers
│   │   ├── test_foo.py
│   │   └── test_bar.py
│   ├── services
│   │   ├── test_faz.py
│   │   └── test_baz.py
├── setup.py

python setup.py bdist_wheel您可以使用或其他选项包装您的产品。或者进行“开发”安装。设置一个python虚拟环境,当你想测试时,在这个目录的根目录下做pip install -e .(“可编辑”设置它,以便python从这个本地目录而不是常规的python模块目录中获取你的包)。现在类似noseorpytest的东西可以扫描树以查找任何名为 test_xxx.py 的内容并运行它。

main.py,脚本和各种测试模块都只是

import foopackage.helpers as helpers

src/services/faz.py 将

from .. import helpers

Python 打包是一种黑暗艺术,但极简主义setup.py将是

#!/usr/bin/env python

from setuptools import find_packages, setup

setup(
    name='foopackage',
    version='1.0.0',
    description='Foo all the Bars',
    packages=find_packages('src'),
    package_dir={'': 'src'},
    scripts=['src/scripts/main.py']
)

推荐阅读