如何编写Python模块/包?

2024-04-23 20:18:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在为工作中的简单任务制作Python脚本,从来没有真正费心将它们打包供其他人使用。现在我被指派为REST API制作一个Python包装器。我完全不知道怎么开始,我需要帮助。

我拥有的:

(只想尽可能具体)我已经准备好了virtualenv,它也是up in github,python的.gitignore文件也在那里,另外,与REST API交互的requests library。就这样。

这是当前目录树

.
├── 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模块的一般的逐步过程。


Tags: 模块文件theingithub脚本restapi
3条回答

因为还没有人讨论这个问题:

What I wanted to do:

Make a python module install-able with "pip install ..."

下面是一个绝对最小的示例,显示了使用setuptoolstwine准备包并将包上载到PyPI的基本步骤。

这绝不是reading at least the tutorial的替代品,它的意义远不止这个非常基本的示例所涵盖的内容。

创建包本身已经包含在这里的其他答案中,因此让我们假设我们已经包含了该步骤,并且我们的项目结构如下:

.
└── 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,在structuredtext中包含一个自述文件作为README.rst

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

此时,我们准备使用setuptools开始打包,如果尚未安装,可以使用pip安装:

pip install setuptools

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

python setup.py sdist

这将创建我们的分发包和egg信息,并生成这样的文件夹结构,我们的包位于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。

由于我们不希望实验污染实时存储库,因此我们为testing repository创建一个帐户,并为上载过程安装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

如我们所见,基本过程并不复杂。正如我前面所说的,还有比这里更多的内容,所以继续并read the tutorial获得更深入的解释。

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模块名称空间的方法。例如,模块名A.B指定名为A的包中名为B的子模块。正如使用模块可以避免不同模块的作者不得不担心彼此的全局变量名一样,使用点式模块名也可以避免多模块包(如NumPy或Python映像库)的作者不得不担心彼此的模块名。

包示例:假设我们有以下文件夹和文件。这里,mymodule.py与之前相同,并且\uu init\uuuu.py是一个空文件:

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

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

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

$ ls
mypackage

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

>>> 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给出了一般准则-请参见Package and Module Names

模块应该有简短的所有小写名称。如果提高了可读性,可以在模块名称中使用下划线。Python包还应该有短的、所有小写的名称,尽管不鼓励使用下划线。

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

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

def helloworld():
   print "hello"

然后您可以导入hello

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

要将许多.py文件分组,请将它们放在文件夹中。python将任何带有__init__.py的文件夹视为模块,您可以将它们称为包

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

您可以按照通常的方式继续处理模块上的import语句。

有关详细信息,请参见6.4. Packages

相关问题 更多 >