简体   繁体   English

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

[英]A simple Hello World setuptools package and installing it with pip

I'm having trouble figuring out how to install my package using setuptools, and I've tried reading the documentation on it and SO posts, but I can't get it to work properly. 我无法确定如何使用setuptools安装我的软件包,我已经尝试阅读它上面的文档和SO帖子,但我无法让它正常工作。 I'm trying to get a simple helloworld application to work. 我正在尝试使用一个简单的helloworld应用程序。 This is how far I got: 这是我得到了多远:

helloworld.py: helloworld.py:

print("Hello, World!")

README.txt: README.txt文件:

Hello, World! readme

MANIFEST.in: MANIFEST.in:

recursive-include images *.gif

setup.py: 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",
)

And I have a blank file called images/hello.gif that I want to include in my package as additional data. 我有一个名为images / hello.gif的空白文件,我希望将其作为附加数据包含在我的包中。 The folder structure looks like this: 文件夹结构如下所示:

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

When I run python setup.py sdist , it generates the dist and helloworld.egg-info successfully. 当我运行python setup.py sdist ,它会成功生成disthelloworld.egg-info When I look at SOURCES.txt under egg-info, it contains the script and the image under the images folder, and the tarball under dist contains them as well. 当我在egg-info下查看SOURCES.txt时,它包含脚本和images文件夹下的图像,而dist下的tarball也包含它们。

However, when I try to run pip install --user helloworld-0.1.tar.gz on the tarball, it successfully installs it, but I can't find the program files helloworld.py and images/hello.gif. 但是,当我尝试在tarball上运行pip install --user helloworld-0.1.tar.gz时,它成功安装了它,但我找不到程序文件helloworld.py和images / hello.gif。

When I look under $HOME/.local/lib/python3.3/site-packages/ , I see the egg-info folder and all of it's contents installed there. 当我查看$HOME/.local/lib/python3.3/site-packages/ ,我看到egg-info文件夹及其中安装的所有内容。 But the $HOME/.local/bin folder doesn't even exist. $HOME/.local/bin文件夹甚至不存在。 Are the program files stores elsewhere? 程序文件存储在别处吗? What am I doing wrong here? 我在这做错了什么? I'm running Arch Linux. 我正在运行Arch Linux。

Okay, so after some effort, I finally managed to get a simple "hello world" example working for setuptools. 好的,经过一番努力,我终于设法得到一个简单的“hello world”示例,用于setuptools。 The Python documentation is usually amazing, but I wish the documentation was better on this in particular. Python文档通常很棒,但我希望文档在这方面更好。

I'm going to write a fairly detailed guide on how I achieved this, and I'll assume no prior background on the reader on this topic. 我将写一篇关于我如何实现这一目标的相当详细的指南,并且我将假设读者没有关于此主题的先前背景。 I hope this comes in handy for others... 我希望这对其他人派上用场......

In order to get this example set up, we'll be creating a package (actually two of them, one for the data files). 为了设置这个例子,我们将创建一个包(实际上是两个包,一个用于数据文件)。 This is the directory structure we'll end up with: 这是我们最终得到的目录结构:

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

Here are the steps: 以下是步骤:

  1. Create the helloworld package. 创建helloworld包。
    1.1 Create the helloworld/ folder as shown in the directory structure above. 1.1创建helloworld/文件夹,如上面的目录结构所示。

    1.2 Add a blank file called __init__.py in the helloworld/ folder. 1.2在helloworld/文件夹中添加一个名为__init__.py的空白文件。
    If you don't add it, the package won't be recognized (run touch __init__.py to create the file on linux/mac machines). 如果你不添加它,将无法识别包(运行touch __init__.py在linux / mac机器上创建文件)。 If you want some code to be executed every time the package is imported, include it in the __init__.py file. 如果要在每次导入包时执行某些代码,请将其包含在__init__.py文件中。

    1.3 Create the the hello.py script file to demonstrate the package functionality. 1.3创建hello.py脚本文件以演示包功能。

Here is the code for 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. 1.4 Create the images/ folder inside the helloworld/ folder. 1.4在helloworld/文件夹中创建images/文件夹。
    Make another blank __init__.py file, because this folder will also be a package. 制作另一个空白的__init__.py文件,因为该文件夹也是一个包。

    1.5 Create the hello.gif file inside the images/ folder. 1.5在images/文件夹中创建hello.gif文件。
    This file won't be an actual gif file. 此文件不是实际的gif文件。 Instead, add plain text just to demonstrate that non-script files can be added and read. 相反,添加纯文本只是为了演示可以添加和读取非脚本文件。

I added the following code in hello.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. 1.6 Test your package 1.6测试你的包裹
    Run python from the test-setuptools folder, which will open the python interpreter. test-setuptools文件夹运行python ,它将打开python解释器。
    Type import helloworld.hello to import the hello.py script in the helloworld package. import helloworld.hello导入helloworld包中的hello.py脚本。 The import should be successful, indicating that you successfully created a package. 导入应该成功,表明您已成功创建包。 Make sure that the package in the images/ folder also works, by typing import helloworld.images 通过输入import helloworld.images ,确保images/文件夹中的包也可以正常工作
    Try instantiating the object that we wrote in hello.py . 尝试实例化我们在hello.py编写的对象。 Type the following commands to make sure everything works as expected: 键入以下命令以确保一切按预期工作:
    hey = helloworld.hello.Hello()
    hey.say_hello()
    hey.open_image()

  2. Create the setup.py file and the remaining files. 创建setup.py文件和其余文件。
    2.1 Create a simple README.txt file. 2.1创建一个简单的README.txt文件。 Mine just has the text: Hello, World! Readme 我的文字就是: Hello, World! Readme Hello, World! Readme inside. Hello, World! Readme内容。

    2.2 Create a MANIFEST.in file with the following contents: 2.2使用以下内容创建MANIFEST.in文件:
    include helloworld/images/hello.gif
    .
    This is very important because it tells setuptools to include the additional data in the source distribution (which we'll generate in a later step). 这非常重要,因为它告诉setuptools在源代码分发中包含其他数据(我们将在后面的步骤中生成)。 Without this, you won't be able to install additional, non .py data to your package. 如果没有此功能,您将无法在软件包中安装其他非.py数据。 See this for additional details and commands. 有关其他详细信息和命令,请参阅

    2.3 Create the setup.py file (see the code below). 2.3创建setup.py文件(参见下面的代码)。
    The most important attributes are packages , include_package_data , and package_data . 最重要的属性是packagesinclude_package_datapackage_data
    .
    The packages attribute contains a list of the packages you want to include for setuptools. packages属性包含要包含在setuptools中的包的列表。 We want to include both the helloworld package and the helloworld.images package that contains our additional data hello.gif . 我们想要包含helloworld包和helloworld.images包,其中包含我们的附加数据hello.gif
    You can make setuptools automatically find these by adding the from setuptools import find_packages import and running the imported find_packages() function. 您可以通过添加from setuptools import find_packages导入并运行导入的find_packages()函数,使setuptools自动找到这些。 Run the interpreter from the test-setuptools folder and test this command to see which packages are found. test-setuptools文件夹运行解释器并测试此命令以查看找到的包。
    .
    The package_data attribute tells setuptools to include additional data. package_data属性告诉setuptools包含其他数据。 It's this command, the helloworld.images package, and the MANIFEST.in file which allow you to install additional data. 它是这个命令, helloworld.images包,以及允许您安装其他数据的MANIFEST.in文件。
    The 'helloworld.images' : ['hello.gif'] key/value pair tells setuptools to include hello.gif inside the helloworld.images package if it exists. 'helloworld.images' : ['hello.gif']键/值对告诉setuptools在helloworld.images包中包含hello.gif如果存在)。 You can also say '' : ['*.gif'] to include any .gif file in any of the included packages. 您还可以说'' : ['*.gif']在任何包含的包中包含任何.gif文件。
    The include_package_data attribute set to True is also necessary for this to work. 设置为Trueinclude_package_data属性也是必须的。
    You can include additional metadata for the package like I have (I think an author is necessary). 您可以像我一样包含其他元数据(我认为是必要的author )。 It's a good idea to add classifiers. 添加分类器是个好主意。 Additional info can be found here . 其他信息可以在这里找到。

Here is the entire setup.py code: 这是整个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. Install and test your package with setuptools. 3.使用setuptools安装并测试您的软件包。

3.1 Create the source distribution  

Run python setup.py sdist from the test-setuptools/ folder to generate the source distribution. test-setuptools/文件夹运行python setup.py sdist以生成源代码分发。
This will create a dist/ folder containing your package, and a helloworld.egg-info/ folder containing metadata such as SOURCE.txt . 这将创建一个包含您的包的dist/文件夹,以及一个包含元数据(如SOURCE.txthelloworld.egg-info/文件夹。
Check SOURCE.txt to see if your the hello.gif image file is included there. 检查SOURCE.txt以查看是否包含hello.gif图像文件。
Open the .tar.gz file under the dist/ folder. 打开dist/文件夹下的.tar.gz文件。 You should see all of the files described in the directory structure we made earlier, including hello.gif and hello.py . 您应该看到我们之前创建的目录结构中描述的所有文件,包括hello.gifhello.py

3.2 Install the distribution  

Install the .tar.gz distribution file by running pip install --user helloworld-0.1.tar.gz from the dist/ folder. 通过从dist/文件夹运行pip install --user helloworld-0.1.tar.gz来安装.tar.gz分发文件。
Check that the package was successfully installed by running pip list . 通过运行pip list检查包是否已成功安装。 The package helloworld should be there. helloworld应该在那里。

That's it! 而已! now you should be able to test your package under any folder. 现在你应该能够在任何文件夹下测试你的包。 Open up the interpreter in any folder except test-setuptools , and try importing the package using import helloworld.hello . test-setuptools之外的任何文件夹中打开解释器,并尝试使用import helloworld.hello导入包。 It should work. 它应该工作。 Then try the commands to instantiate the object and open the image file using the hey.open_image() command again. 然后尝试使用命令实例化对象并再次使用hey.open_image()命令打开图像文件。 It should still work! 它应该仍然有用!

You can view exactly which files were installed by pip, and where they are, by uninstalling the package. 您可以通过卸载软件包来准确查看pip安装的文件及其位置。 Mine looked like this: 我看起来像这样:

[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

As you can see, it successfully installed the additional data file hello.gif , and because we converted the relative path to an absolute path in hello.py , it can read the file just fine. 如您所见,它成功安装了附加数据文件hello.gif ,并且因为我们将相对路径转换为hello.py的绝对路径,所以它可以正常读取文件。
You can then share this package on PyPI for the rest of the world to use! 然后,您可以在PyPI上共享此包,供世界其他地方使用! The instructions on uploading to PyPI are fairly straightforward and can be found here and here . 上传到PyPI的说明非常简单,可以在这里这里找到。

Once it's online in PyPI, people can search for your package using pip search . 一旦它在PyPI中联机,人们就可以使用pip search来搜索你的包。 Or alternatively, running pip install --user [package-name] will tell pip to search the online PyPI directory for that package name. 或者,运行pip install --user [package-name]将告诉pip在联机PyPI目录中搜索该包名。 If it exists, it will install it. 如果它存在,它将安装它。

You can run that command for any python package that in PyPI for an easy install so you aren't mucking around with build files. 你可以为PyPI中的任何python包运行该命令,以便于安装,这样你就不会破坏构建文件。

I hope this saves people a bunch of headaches. 我希望这可以为人们带来一些麻烦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM