首页 > 解决方案 > 用于在分发和本地、非构建开发/使用时导入的 python 包结构

问题描述

我创建了一个非常简单的用例来模拟我的更大努力,如下所述。我有一个包裹(foo)。我打算使用包执行本地开发/测试(即运行 bin/cli_script.py 或 ipython/import foo)。我通过管理我的环境和设置 PYTHONPATH 来做到这一点。一旦满意,我打算构建一个轮子,然后 pip install 它进行部署测试(尽管我不必这样做,但我在完全不同的 venv 中执行此操作)。如果我让我的导入语句适用于本地开发,它会在包中使用导入中断,反之亦然。永远不能让这两种方法一起工作。

$ tree foo
foo
├── bin
│   └── cli_script.py
├── build
├── contributing.md
├── dist
├── foo
│   ├── a_model.py
│   ├── b_model.py
│   ├── common.py
│   ├── example_module.py
│   └── __init__.py
├── LICENSE
├── makefile
├── README.md
├── requirements.txt
├── setup_environment.sh
├── setup.py
└── tests

在包中,foo subdir 是我的库文件夹,旨在与普通的 python 用语一起使用(从 foo 导入 a_model 或导入 foo 等)。有一个 bin/cli_script.py 驱动程序也可以导入和使用包库。此脚本旨在安装在 virtualenv 中,并在 venv 环境中的路径上可用。

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

# Add our unit testing area
#import sys
#sys.path.append('./tests')

setuptools.setup(
    name="foo",                               # Replace with your package name
    version="0.0.1",                               # see pep 440
    author="foobar",
    author_email="blah@email.com",
    maintainer="***",
    maintainer_email="***",
    description="Test",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://www.google.com",  # github pages
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.0',
    install_requires=[],                           # list 3rd party packages/versions
    #test_suite="tests",                           # folder for unit/functional tests
    setup_requires=['wheel'],
    scripts=['bin/cli_script.py'],                 # callable script to register (updates PATH)
)

common.py 的内容:

class CommonModel:
    """ common to all device """

    def __init__(self):
        self.subtype = 'common'
        self.status = ""
        self.serial = ""

    def show(self):
        print("\tsubtype: %s" % self.subtype)
        print("\tstatus: %s" % self.status)
        print("\tserial: %s" % self.serial)

a_model.py 的内容:

import common

class A_Model(common.CommonModel):
    """ Model A """

    def __init__(self):
        super().__init__()

        self.subtype = 'a_model'
        self.a_new_param = 'blah'

b_model的内容:

import common

class B_Model(common.CommonModel):
    """ Model B """

    def __init__(self):
        super().__init__()
        self.subtype = 'b_model'

我觉得答案将是我如何构建我的init .py 文件,现在它是空的。任何帮助都非常感谢并很高兴包含对实际错误的额外捕获(最初不想让这个膨胀太多)。

标签: pythonpackage

解决方案


是的,我不小心弄坏了我认为一致的东西(为了别的东西)。基本上它是我的 PYTHONPATH - 它指向包含库/模块的包子文件夹(在我的描述中,它如下所示并通过将其设置为包文件夹来修复。即:

$ tree foo
foo                 **<----PYTHONPATH (fixed)**

├── bin
│   └── cli_script.py
├── build
├── contributing.md
├── dist
├── foo              **<----PYTHONPATH (Broken)**
│   ├── a_model.py
│   ├── b_model.py
│   ├── common.py
│   ├── example_module.py
│   └── __init__.py
├── LICENSE
├── makefile
├── README.md
├── requirements.txt
├── setup_environment.sh
├── setup.py
└── tests

推荐阅读