如何编写Python模块/包?

我一直在为工作中的简单任务制作Python脚本,并且从来没有真正困扰他人打包供其他人使用。 现在我已经被分配到一个REST API的Python包装器。 我完全不知道如何开始,我需要帮助。

我拥有的:

(只想尽可能具体)我准备好了virtualenv,它也在github中,python的.gitignore文件也存在,此外还有用于与REST API交互的请求库。 而已。

这是当前的目录树

.
├── bin
│   └── /the usual stuff/
├── include
│   └── /the usual stuff/
├── lib
│   └── python2.7
│       └── /the usual stuff/
├── local
│   └── /the usual stuff/
└── README.md

27 directories, 280 files

我甚至不知道把.py文件放在哪里,如果我做到的话。

我想做什么:

使用“pip install ...”安装python模块

如果可能的话,我需要一个一步一步的编写Python模块的过程。


模块是一个包含Python定义和语句的文件。 文件名是带有后缀.py的模块名称

创建hello.py然后将以下函数编写为其内容:

def helloworld():
   print "hello"

然后你可以导入hello

>>> import hello
>>> hello.helloworld()
'hello'
>>>

将许多.py文件放在一个文件夹中。 任何具有__init__.py文件夹都被python视为模块,您可以将它们称为包

|-HelloModule
  |_ __init__.py
  |_ hellomodule.py

通常情况下,您可以使用模块上的导入语句。

有关更多信息,请参阅6.4。 包。


Python 3 - 2015年11月18日更新

找到接受的答案很有用,但希望根据我自己的经验为其他人的利益扩大几点。

模块:模块是一个包含Python定义和语句的文件。 文件名是带有后缀.py的模块名称。

模块示例 :假设我们在当前目录中有一个单独的python脚本,在这里我称之为mymodule.py

文件mymodule.py包含以下代码:

def myfunc():
    print("Hello!")

如果我们从当前目录运行python3解释器,我们可以通过以下几种不同的方式导入并运行myfunc函数(通常只需选择以下选项之一):

>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!

好吧,这很容易。

现在假设您需要将此模块放入其自己的专用文件夹中以提供模块名称空间,而不是仅从当前工作目录运行它。 这是值得解释的概念的地方。

:包是通过使用“虚线模块名称”来构造Python模块名称空间的一种方式。 例如,模块名称AB在名为A的包中指定名为B的子模块。就像模块的使用一样,不同模块的作者不必担心彼此的全局变量名称,使用虚线模块名称可以节省作者像NumPy或Python Imaging Library这样的多模块软件包不必担心彼此的模块名称。

包示例 :现在让我们假设我们有以下文件夹和文件。 这里, mymodule.py与之前相同, __init__.py是一个空文件:

.
└── mypackage
    ├── __init__.py
    └── mymodule.py

需要__init__.py文件才能使Python将目录视为包含包。 有关更多信息,请参阅稍后提供的模块文档链接。

我们当前的工作目录比名为mypackage的普通文件夹高一级

$ ls
mypackage

如果我们现在运行python3解释器,我们可以通过以下几种方式导入并运行包含所需函数myfunc的模块mymodule.py (通常只需选择以下选项之一):

>>> import mypackage
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> import mypackage.mymodule
>>> mypackage.mymodule.myfunc()
Hello!
>>> from mypackage import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mypackage.mymodule import myfunc
>>> myfunc()
Hello!
>>> from mypackage.mymodule import *
>>> myfunc()
Hello!

假设Python 3,在:Modules上有很好的文档

关于封装和模块的命名规范,一般准则在PEP-0008中给出 - 请参阅封装和模块名称

模块应该有简短的全小写名称。 如果提高可读性,则可以在模块名称中使用下划线。 尽管不建议使用下划线,Python包也应该有简短的全小写名称。


由于没有人涵盖OP的这个问题:

我想做什么:

使用“pip install ...”安装python模块

这里是一个绝对简单的例子,展示了使用setuptoolstwine准备和上传你的包到PyPI的基本步骤。

这至少不会取代阅读教程,它比这个非常基本的例子还要多。

创建包本身已经被其他答案覆盖了,所以让我们假设我们已经包含了这一步,并且我们的项目结构如下所示:

.
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

为了使用setuptools进行打包,我们需要添加一个setup.py文件,这会进入我们项目的根文件夹:

.
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

至少,我们为我们的包指定元数据,我们的setup.py将如下所示:

from setuptools import setup

setup(
    name='hellostackoverflow',
    version='0.0.1',
    description='a pip-installable package example',
    license='MIT',
    packages=['hellostackoverflow'],
    author='Benjamin Gerfelder',
    author_email='benjamin.gerfelder@gmail.com',
    keywords=['example'],
    url='https://github.com/bgse/hellostackoverflow'
)

由于我们已设置license='MIT' ,因此我们在LICENCE.txt一个副本包含在我们的项目中, LICENCE.txt reStructuredText中的readme文件包含为README.rst

.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

在这一点上,我们准备开始使用setuptools进行setuptools ,如果我们没有安装它,我们可以用pip安装它:

pip install setuptools

为了做到这一点,并创建一个source distribution ,在我们的项目根文件夹中,我们从命令行调用我们的setup.py ,指定我们需要sdist

python setup.py sdist

这将创建我们的分发包和egg-info,并产生一个像这样的文件夹结构,以及我们的dist包中的包:

.
├── dist/
├── hellostackoverflow.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
    ├── __init__.py
    └── hellostackoverflow.py

在这一点上,我们有一个可以使用pip安装的软件包,所以从我们的项目根目录(假设你有这个例子中的所有命名):

pip install ./dist/hellostackoverflow-0.0.1.tar.gz

如果一切顺利,我们现在可以打开一个Python解释器,我会在项目目录之外的某个地方说出来,以避免混淆,并尝试使用我们闪亮的新包:

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from hellostackoverflow import hellostackoverflow
>>> hellostackoverflow.greeting()
'Hello Stack Overflow!'

现在我们已经确认软件包的安装和工作,我们可以将其上传到PyPI。

由于我们不想通过实验来污染实时存储库,因此我们为测试存储库创建一个帐户,并为上传过程安装twine

pip install twine

现在我们快到了,创建账户后,我们只需简单地告诉twine上传我们的软件包,它会询问我们的凭据并将我们的软件包上传到指定的存储库:

twine upload --repository-url https://test.pypi.org/legacy/ dist/*

我们现在可以在PyPI测试存储库中登录我们的帐户,并惊叹我们刚刚上传的软件包一段时间,然后使用pip抓取它:

pip install --index-url https://test.pypi.org/simple/ hellostackoverflow

我们可以看到,基本过程并不复杂。 正如我刚才所说,除此之外还有很多内容,所以请继续阅读教程,以获得更深入的解释。

链接地址: http://www.djcxy.com/p/26289.html

上一篇: How to write a Python module/package?

下一篇: Python package to manage module system in HPCs