对打包 python 个项目感到困惑

Confused about packing python projects

我已经在 Python 中编写代码很长时间了,但从未真正尝试打包一段代码以便我可以共享。我开始阅读 https://python-packaging.readthedocs.io/en/latest/

我从最简单的情况开始,假设我想共享一个名为 'clipper' 的模块,唯一重要的是一个名为 Clipper 的 class。看来如果我使用 setuptools 我应该在某个地方创建文件夹

clipper/clipper

并在内部剪辑器中放置一个文件 __init__.py

用class Clipper 的定义。到目前为止,一切都很好。理论上,安装包后,class的使用方式为:

import clipper
cl = clipper.Clipper()

我的问题是,我假设在开发过程中和任何安装之前,相同的代码应该可以工作。我的意思是,前面的代码应该创建一个对象的实例。但这将如何工作?我应该如何设置 PYTHONPATH 才能使之前的导入真正起作用?

也许我真的错了,我认为打包比编码更容易,但我花了一些时间但我不明白。有什么帮助吗?

与其修改您的 Python 路径,不如将打包的模块安装为可编辑版本,您的环境会为您处理。当您 运行ning 作为可编辑版本时,您将能够更改本地开发实例上的代码。

例如,假设您有 Pip,您可以 运行 在第一个 'clipper' 文件夹(与您在打包期间创建的 setup.py 文件相同的文件夹)中执行以下命令:

pip install -e .
  • -e表示可编辑
  • . 表示安装位于当前文件夹中的包。

2015 年的 SO 回答中有更多详细信息:

您的目录树看起来有点像这样:

~/clipper/
    setup.py
    clipper/
        __init__.py
        clipper.py

setup.py 文件包含告诉 Python 如何 'parse' 您的包的信息。项目名称、版本和要包含的包等内容都在此处定义。对于您的示例,setup.py 可能如下所示:

from distutils.core import setup

setup(
    name="Clipper",
    # A name for your package, typically your project name
    description="My first package",
    # A short description
    version="1.0.0",
    # A version specification
    packages=["clipper"]
    # A list of packages to include
)

clipper 中,clipper.py 包含实际的 Clipper class:

class Clipper(object):
    def __init__(self):
        pass

    def foo(self):
        print("Invoked foo!")

__init__.py 是一种特殊类型的文件。它定义了 public 接口来与你的包进行交互。通常,它 import 所有 public 函数和 class 是:

from .clipper import Clipper

最后,要将它变成一个合适的包,运行 python3 setup.py sdist。这会为您的包创建 source distribution 并允许您导入它 1。让我们现在试试看。导航回 ~/clipper/ 并开始 Python:

>>> from clipper import Clipper
>>> c = Clipper()
>>> c.foo()
Invoked foo!
>>>

这里是 'real' 包目录的示例:

~/calculator/
    setup.py
    calculator/
        __init__.py
        add.py
        substract.py

setup.py

from distutils.core import setup

setup(
    name="Calculator",
    description="Calculate stuff!",
    version="1.0.0",
    packages=["calculator"]
)

__init__.py

from .add import *
from .substract import *

add.py

def add(a, b):
    """Return `a` + `b`."""
    return a + b

substract.py

def substract(a, b):
    """Return `a` - `b`."""
    return a - b

有关详细信息,请参阅 Python tutorial on packaging

1 您可能会收到一些关于缺少信息的警告,但您现在可以忽略它。