提问者:小点点

如何编写Python模块/包?


我一直在为工作中的简单任务编写Python脚本,从未真正费心将它们打包以供他人使用。现在我被指派为RESTAPI制作Python包装器。我完全不知道如何开始,我需要帮助。

我所拥有的:

(只是想尽可能具体)我已经准备好了虚拟环境,它也在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文件,如果我做过的话。

我想做的是:

使一个python模块可安装与"pip安装..."

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


共3个答案

匿名用户

模块是包含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。派克

文件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 Imaging Library)的作者不必担心彼此的模块名。

包示例:现在假设我们有以下文件夹和文件。这里,我的模块。py与之前相同,并且_init。py是一个空文件:

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

这个uuu init uuuu。py文件是使Python将目录视为包含包所必需的。有关更多信息,请参阅后面提供的模块文档链接。

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

$ 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,有优秀的留档:模块

在包和模块的命名约定方面,PEP-0008中给出了一般指南-请参阅包和模块名称

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

匿名用户

由于还没有人涉及OP的这个问题:

我想做的是:

使一个python模块可安装与"pip安装..."

下面是一个绝对简单的示例,显示了使用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',所以我们在项目中包含一个副本作为许可证。txt,与重构文本中的自述文件一起显示为自述文件。rst

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

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

pip install setuptools

为了做到这一点并创建源代码分发版,我们在项目根文件夹中调用设置。py从命令行,指定我们想要的sdist

python setup.py sdist

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

正如我们所看到的,基本过程并不是很复杂。正如我前面所说的,它的内容比这里所涵盖的要多得多,所以请继续阅读教程以获得更深入的解释。