Python模块单个文件如何使用pip和PyPI安装?

How can a Python module single file be installed using pip and PyPI?

我正在尝试学习如何通过 PyPI 上的 pip 制作一个 Python 模块。为此,我正在使用 PyPI 测试站点 (https://testpypi.python.org/pypi) 进行测试,并尝试为该模块创建一个 setup.py。我的模块是根目录下的一个文件,我无法成功安装它。我想了解如何执行此操作。

下面,我将详细说明我正在采取的步骤。我怀疑问题出在我如何写 setup.py.

仓库剖析如下:

.
├── examples_1.py
├── LICENSE
├── MANIFEST.in
├── README.rst
├── setup.py
└── supermodule.py

请注意,该模块只是目录根目录中的文件 supermodule.py。另请注意,文件 examples_1.py 不会 包含在模块包的安装中。

setup.py内容如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import setuptools

def read(*paths):

    with open(os.path.join(*paths), "r") as filename:
        return filename.read()

def main():

    setuptools.setup(
        name             = "supermodule",
        version          = "2015.10.30.0820",
        description      = "super utilities",
        long_description = (read("README.rst")),
        url              = "https://github.com/johndrake1/junk",
        author           = "John Drake",
        author_email     = "j.drake@sern.ch",
        license          = "GPLv3",
        package_data     = {
            "": [
                "*.txt",
                "*.md",
                "*.rst",
                "*.py"
            ]
        }
    )

if __name__ == "__main__":
    main()

我通过以下过程来注册、上传和安装包:

python setup.py register -r https://testpypi.python.org/pypi
python setup.py sdist upload -r https://testpypi.python.org/pypi
sudo pip install -i https://testpypi.python.org/pypi supermodule

在源代码分发中,supermodule-2015.10.30.0820.tar.gz,我可以看到以下目录结构:

.
└── supermodule-2015.10.30.0820
    ├── LICENSE
    ├── MANIFEST.in
    ├── PKG-INFO
    ├── README.rst
    ├── setup.cfg
    ├── setup.py
    ├── supermodule.egg-info
    │   ├── dependency_links.txt
    │   ├── PKG-INFO
    │   ├── SOURCES.txt
    │   └── top_level.txt
    └── supermodule.py

所以,看来打包上传工作正常,包含了根目录下的模块文件supermodule.py。但是,当我安装包时,我在本地安装了以下文件:

/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0820.dist-info
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0820.dist-info/DESCRIPTION.rst
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0820.dist-info/METADATA
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0820.dist-info/RECORD
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0820.dist-info/WHEEL
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0820.dist-info/metadata.json
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0820.dist-info/top_level.txt

您可以看到 supermodule.py 文件不存在,无法在 Python 实例中导入。我应该如何将此文件包含在安装中,以便它可以在 Python 中导入?


编辑:根据@DeanFenster 的建议,我将文件 supermodule.py 移至 supermodule/__init__.py 并将 setup.py 更改为以下内容:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import setuptools

def read(*paths):
    with open(os.path.join(*paths), "r") as filename:
        return filename.read()

def main():

    setuptools.setup(
        name             = "supermodule",
        version          = "2015.10.30.0902",
        description      = "super utilities",
        long_description = (read("README.rst")),
        url              = "https://github.com/johndrake1/junk",
        author           = "John Drake",
        author_email     = "j.drake@sern.ch",
        license          = "GPLv3",
        packages         = ["supermodule"]
    )

if __name__ == "__main__":
    main()

在注册、上传和安装之后,安装使模块可导入,并在本地安装了以下文件:

/usr/local/lib/python2.7/dist-packages/supermodule
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0902.dist-info
/usr/local/lib/python2.7/dist-packages/supermodule/__init__.py
/usr/local/lib/python2.7/dist-packages/supermodule/__init__.pyc
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0902.dist-info/DESCRIPTION.rst
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0902.dist-info/METADATA
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0902.dist-info/RECORD
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0902.dist-info/WHEEL
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0902.dist-info/metadata.json
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.0902.dist-info/top_level.txt

这种方法很好用,但我还是想知道当模块是单个文件的形式时如何安装。


编辑:根据@Xk0nSid 的建议,我将 setup.py 更改为以下内容:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import setuptools

def read(*paths):
    with open(os.path.join(*paths), "r") as filename:
        return filename.read()

def main():

    setuptools.setup(
        name             = "supermodule",
        version          = "2015.10.30.1001",
        description      = "super utilities",
        long_description = (read("README.rst")),
        url              = "https://github.com/johndrake1/junk",
        author           = "John Drake",
        author_email     = "j.drake@sern.ch",
        license          = "GPLv3",
        py_modules       = ["supermodule"],
        entry_points     = """
            [console_scripts]
            supermodule = supermodule:supermodule
        """
    )

if __name__ == "__main__":
    main()

在注册、上传和安装之后,安装使模块可导入,并在本地安装了以下文件:

/usr/local/bin/supermodule
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.1001.dist-info
/usr/local/lib/python2.7/dist-packages/supermodule.py
/usr/local/lib/python2.7/dist-packages/supermodule.pyc
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.1001.dist-info/DESCRIPTION.rst
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.1001.dist-info/METADATA
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.1001.dist-info/RECORD
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.1001.dist-info/WHEEL
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.1001.dist-info/entry_points.txt
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.1001.dist-info/metadata.json
/usr/local/lib/python2.7/dist-packages/supermodule-2015.10.30.1001.dist-info/top_level.txt

这种方法成功地处理了模块的单文件形式。

尝试对单个文件使用类似这样的方法。以下是目录结构:

.
├── example.py
├── LICENSE
├── README.md
└── setup.py

0 directories, 4 files

setup.py

from setuptools import setup

setup(
    name='example',
    version='0.1.0',
    py_modules=['example'],
    install_requires=[
        'exampledep',
    ],
    entry_points='''
        [console_scripts]
        example=example:example
    ''',
)

以上对我有用。这就是示例文件的样子。

def example():
    # Note: You can use sys.argv here
    print "Hi! I'm a command written in python."

也可以这样导入:

import example
example.example()
# or
from example import example
example()

希望这对您有所帮助。

安装需要

install_requires 用于为您的 module/application 定义 dependencies。例如,在这种情况下 example 模块依赖于 exampledep。因此,当有人执行 pip install example 时,pip 也会安装 exampledep,因为它在依赖项中列出。

入口点

这通常是包的最终用户可能想要使用的可调用项。这通常是可调用的,用于命令行。您可以查看 this question or this 文档了解更多详细信息。