一个简单的 Hello World setuptools 包并使用 pip 安装它

Posted

技术标签:

【中文标题】一个简单的 Hello World setuptools 包并使用 pip 安装它【英文标题】:A simple Hello World setuptools package and installing it with pip 【发布时间】:2014-03-29 20:52:24 【问题描述】:

我无法弄清楚如何使用 setuptools 安装我的包,我已经尝试阅读它的文档和 SO 帖子,但我无法让它正常工作。我正在尝试让一个简单的 helloworld 应用程序工作。这是我走了多远:

helloworld.py:

print("Hello, World!")

README.txt:

Hello, World! readme

MANIFEST.in:

recursive-include images *.gif

setup.py:

from setuptools import setup, find_packages

setup(
    name='helloworld',
    version='0.1',
    license='BSD',
    author='gyeh',
    author_email='hello@world.com',
    url='http://www.hello.com',
    long_description="README.txt",
    packages=find_packages(),
    scripts = ['helloworld.py'],
    package_data=
        "" : ["images/*.gif"]
    ,
    data_files=[('images', ['images/hello.gif'])],
    description="Hello World testing setuptools",
)

我有一个名为 images/hello.gif 的空白文件,我想将它作为附加数据包含在我的包中。文件夹结构如下所示:

testsetup/  
|-- helloworld.py  
|-- images/  
|-- --- hello.gif  
|-- MANIFEST.in  
|-- README.txt  
|-- setup.py  

当我运行python setup.py sdist 时,它会成功生成disthelloworld.egg-info。当我查看 egg-info 下的 SOURCES.txt 时,它包含 images 文件夹下的脚本和图像,并且 dist 下的 tarball 也包含它们。

但是,当我尝试在 tarball 上运行 pip install --user helloworld-0.1.tar.gz 时,它成功安装了它,但我找不到程序文件 helloworld.py 和 images/hello.gif。

当我查看$HOME/.local/lib/python3.3/site-packages/ 时,我看到了 egg-info 文件夹及其所有内容。但是$HOME/.local/bin 文件夹甚至不存在。程序文件是否存储在其他地方?我在这里做错了什么?我正在运行 Arch Linux。

【问题讨论】:

【参考方案1】:

好的,经过一番努力,我终于设法获得了一个适用于 setuptools 的简单 “hello world” 示例。 Python 文档通常很棒,但我希望文档在这方面做得更好。

我将写一个相当详细的指南来说明我是如何做到这一点的,并且我假设读者没有关于这个主题的任何背景知识。我希望这对其他人有用...

为了设置这个示例,我们将创建一个包(实际上是其中的两个,一个用于数据文件)。这是我们最终的目录结构:

test-setuptools/
|-- helloworld/
|-- --- hello.py
|-- --- images/
|-- --- --- hello.gif
|-- --- --- __init__.py
|-- --- __init__.py
|-- MANIFEST.in
|-- README.txt
|-- setup.py

步骤如下:

    创建helloworld 包。 1.1创建helloworld/文件夹如上图目录结构。

    1.2 在helloworld/ 文件夹中添加一个名为__init__.py 的空白文件。 如果不添加,将无法识别包(运行touch __init__.py 在linux/mac 机器上创建文件)。如果您希望每次导入包时都执行一些代码,请将其包含在__init__.py 文件中。

    1.3 创建hello.py 脚本文件来演示包功能。

这是hello.py的代码:

import os

"""
Open additional data files using the absolute path,
otherwise it doesn't always find the file.
"""
# The absolute path of the directoy for this file:
_ROOT = os.path.abspath(os.path.dirname(__file__))

class Hello(object):
    def say_hello(self):
        return "Hello, World!"
    def open_image(self):
        print("Reading image.gif contents:")

        # Get the absolute path of the image's relative path:
        absolute_image_path = os.path.join(_ROOT, 'images/hello.gif')

        with open(absolute_image_path, "r") as f:
            for line in f:
                print(line)

    1.4 在helloworld/ 文件夹内创建images/ 文件夹。 再创建一个空白的__init__.py 文件,因为这个文件夹也是一个包。

    1.5 在images/ 文件夹中创建hello.gif 文件。 此文件不是实际的 gif 文件。相反,添加纯文本只是为了证明可以添加和读取非脚本文件。

我在hello.gif中添加了以下代码:

This should be the data inside hello.gif...
...but this is just to demonstrate setuptools,
so it's a dummy gif containing plain text

    1.6 测试你的包 从test-setuptools 文件夹运行python,这将打开python 解释器。 键入import helloworld.hello 以导入helloworld 包中的hello.py 脚本。导入应该是成功的,说明你成功创建了一个包。通过键入 import helloworld.images 确保 images/ 文件夹中的包也可以工作 尝试实例化我们在hello.py 中编写的对象。键入以下命令以确保一切正常:hey = helloworld.hello.Hello()hey.say_hello()hey.open_image()

    创建setup.py 文件和其余文件。 2.1 创建一个简单的README.txt 文件。我的只有文字:Hello, World! Readme 里面。

    2.2 创建一个MANIFEST.in 文件,内容如下:include helloworld/images/hello.gif . 这非常重要,因为它告诉 setuptools 在源分发中包含附加数据(我们将在后面的步骤中生成)。没有这个,你将无法在你的包中安装额外的非.py 数据。有关其他详细信息和命令,请参阅 this。

    2.3 创建setup.py 文件(参见下面的代码)。 最重要的属性是packagesinclude_package_datapackage_data。 .packages 属性包含要包含在 setuptools 中的软件包列表。我们希望同时包含helloworld 包和包含我们的附加数据hello.gifhelloworld.images 包。 您可以通过添加 from setuptools import find_packages 导入并运行导入的 find_packages() 函数使 setuptools 自动找到这些。从test-setuptools 文件夹运行解释器并测试此命令以查看找到了哪些包。 .package_data 属性告诉 setuptools 包括附加数据。正是这个命令、helloworld.images 包和MANIFEST.in 文件允许您安装其他数据。'helloworld.images' : ['hello.gif'] 键/值对告诉 setuptools 将 hello.gif 包含在 helloworld.images 包中(如果存在)。您也可以说 '' : ['*.gif'] 以在任何包含的包中包含任何 .gif 文件。 设置为 Trueinclude_package_data 属性也是此操作所必需的。 您可以像我一样为包添加其他元数据(我认为author 是必要的)。添加分类器是个好主意。更多信息可以在here找到。

这是整个setup.py 代码:

from setuptools import setup

setup(
    name='helloworld',
    version='0.1',
    license='BSD',
    author='gyeh',
    author_email='hello@world.com',
    url='http://www.hello.com',
    long_description="README.txt",
    packages=['helloworld', 'helloworld.images'],
    include_package_data=True,
    package_data='helloworld.images' : ['hello.gif'],
    description="Hello World testing setuptools",
)

. 3. 使用 setuptools 安装和测试你的包。

3.1 Create the source distribution  

test-setuptools/ 文件夹运行python setup.py sdist 以生成源分发。 这将创建一个包含您的包的dist/ 文件夹,以及一个包含诸如SOURCE.txt 等元数据的helloworld.egg-info/ 文件夹。 检查SOURCE.txt 以查看您的hello.gif 图像文件是否包含在其中。 打开dist/ 文件夹下的.tar.gz 文件。您应该会看到我们之前创建的目录结构中描述的所有文件,包括hello.gifhello.py

3.2 Install the distribution  

通过从dist/ 文件夹运行pip install --user helloworld-0.1.tar.gz 来安装.tar.gz 分发文件。 通过运行pip list 检查软件包是否已成功安装。包helloworld 应该在那里。

就是这样!现在你应该可以在任何文件夹下测试你的包了。在除test-setuptools 之外的任何文件夹中打开解释器,并尝试使用import helloworld.hello 导入包。它应该工作。然后尝试使用命令实例化对象并再次使用hey.open_image() 命令打开图像文件。它应该仍然有效!

您可以通过卸载软件包来准确查看 pip 安装了哪些文件以及它们的位置。 我的看起来像这样:

[gyeh@gyeh package]$ pip uninstall helloworld
Uninstalling helloworld:
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld-0.1-py3.3.egg-info
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/__init__.py
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/__pycache__/__init__.cpython-33.pyc
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/__pycache__/hello.cpython-33.pyc
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/hello.py
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/images/__init__.py
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/images/__pycache__/__init__.cpython-33.pyc
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/images/hello.gif
Proceed (y/n)? y
  Successfully uninstalled helloworld

如您所见,它成功安装了附加数据文件hello.gif,并且由于我们将hello.py中的相对路径转换为绝对路径,它可以正常读取文件。 然后,您可以在 PyPI 上分享这个包,供世界其他地方使用!上传到 PyPI 的说明非常简单,可以在 here 和 here 找到。

一旦它在 PyPI 中上线,人们就可以使用 pip search 搜索您的包。或者,运行pip install --user [package-name] 将告诉 pip 在在线 PyPI 目录中搜索该包名称。如果存在,它将安装它。

您可以为 PyPI 中的任何 python 包运行该命令,以便轻松安装,这样您就不会胡乱处理构建文件。

我希望这可以为人们省去很多麻烦。

【讨论】:

非常感谢。您的示例应该是官方文档的一部分!!我也让我的包裹工作了。再次感谢! 这是给新手的官方指南 如果有人得到Failed building wheel for helloworld,你可能需要先pip install wheel

以上是关于一个简单的 Hello World setuptools 包并使用 pip 安装它的主要内容,如果未能解决你的问题,请参考以下文章

简单的组装过程(Hello world)

简单描述hello world中到底发生了什么

c++入门题(NOI)~太简单啦——输出“Hello World!”

c++入门题(NOI)~太简单啦——输出“Hello World!”

csharp 简单的Hello World C#

Spring Batch 简单应用 (Hello World)