一个简单的 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
时,它会成功生成dist
和helloworld.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
文件(参见下面的代码)。
最重要的属性是packages
、include_package_data
和package_data
。
.packages
属性包含要包含在 setuptools 中的软件包列表。我们希望同时包含helloworld
包和包含我们的附加数据hello.gif
的helloworld.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 文件。
设置为 True
的 include_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.gif
和hello.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 安装它的主要内容,如果未能解决你的问题,请参考以下文章
c++入门题(NOI)~太简单啦——输出“Hello World!”