如何编写Python模块/软件包?


375

我一直在为工作中的简单任务制作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模块的逐步过程。


15
我将从教程(2.7)的第6章开始,或者从3.x的此处开始。 在互联网上搜索python模块教程,您会发现很多其他内容。
罗兰·史密斯

6
没有人回答点子部分
whackamadoodle3000 '17

github.com/MacHu-GWU/pygitrepo-project这个库可以帮助您从头开始创建项目框架,并且所需的功能是开箱即用的。
MacSanhe

Answers:


424

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

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

def helloworld():
   print "hello"

然后,您可以导入hello

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

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

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

您可以按照通常的方式在模块上使用import语句。

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


7
最后一个是:从HellowModule导入hellomodule吗?可以在模块文件夹中打个招呼

目前正在使用Python,这个答案必须是我遇到的最有用的答案之一。很好地解释了,谢谢。
Darren Wainwright

“ pip install”命令将不起作用,您也必须在同一目录中才能使用它
Math Coder 101,

234

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,以下位置提供了出色的文档:模块

关于程序包和模块的命名约定,PEP-0008中给出了通用准则-请参阅程序包和模块名称

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


5
很好的简单解释。如果要在mypackage中保留另一个文件夹怎么办?
阿努·古普塔

3
包含内容完全取决于您写的内容。如果您将东西放在模块上的函数之外,则在调用like时将其触发import mypackage。如果您只想从模块(甚至文件)中导入功能,则更好from module import function。在子文件夹的情况下from subfolder.module import function,您可以简单地调用function()witthout而不使用其他代码部分。另外,from module import *如果您确实不需要,请不要使用。
m3nda

5
剩下的唯一问题是如何获取包以导入所有内容import mypackage?添加import mymodule__init__.py不工作..
576i的

整洁的解释!但是,我有一个问题,如果numpy是一个包,我该如何在解释器中执行numpy.cos(1),因为这似乎是两者之间丢失的模块名称。没有?
user1935724 '17

3
点子怎么样?
whackamadoodle3000 '17

199

由于尚无人讨论过OP的这个问题:

我想做的是:

使用“ pip install ...”制作可安装的python模块

这是一个绝对的最小示例,显示了使用setuptools和准备软件包并将其上传到PyPI的基本步骤twine

这绝不能代替阅读至少本教程,它比这个非常基本的示例所涵盖的内容要多得多。

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

.
└── 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在reStructuredText中添加了一个自述文件,如下所示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-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

我们可以看到,基本过程不是很复杂。正如我之前所说的,它所包含的内容远不止本文所述,因此请继续阅读本教程以获取更深入的说明。


我的软件包会在之后发布setuptools吗?
U10转发

@ U9-Forward否,发布已完成twine,但是您可以使用创建它之后在发布之前在本地测试您的包setuptools
bgse

9

定义所选命令后,只需将保存的文件拖放到python程序文件中的Lib文件夹中即可。

>>> import mymodule 
>>> mymodule.myfunc()

2

制作一个名为“ hello.py”的文件

如果您使用的是Python 2.x

def func():
    print "Hello"

如果您使用的是Python 3.x

def func():
    print("Hello")

运行文件。然后,您可以尝试以下操作:

>>> import hello
>>> hello.func()
Hello

如果您想稍微努力一点,可以使用以下方法:

如果您使用的是Python 2.x

def say(text):
    print text

如果您使用的是Python 3.x

def say(text):
    print(text)

看到定义旁边括号中的一个吗?那很重要。您可以在定义中使用它。

文本-​​当您希望程序说出想要的内容时可以使用它。根据其名称,它是文本。希望您知道文本的含义。它的意思是“单词”或“句子”。

运行文件。然后,如果您使用的是Python 3.x,则可以尝试以下操作:

>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test

对于Python 2.x-我猜与Python 3相同吗?不知道。如果我在Python 2.x上犯了一个错误,请纠正我(我知道Python 2,但是我与Python 3一起使用)


2

我创建了一个项目,以轻松地从头开始创建项目框架https://github.com/MacHu-GWU/pygitrepo-project

假设您可以创建一个测试项目learn_creating_py_package

您可以了解具有不同用途的组件,例如

  • 创建virtualenv
  • 自行安装
  • 运行单元测试
  • 运行代码覆盖率
  • 建立文件
  • 部署文件
  • 在不同的python版本中运行unittest
  • 部署到PYPI

使用的好处pygitrepo是,这些繁琐的自动创建本身和适应你package_nameproject_namegithub_accountdocument host servicewindows or macos or linux

这是学习像pro一样开发python项目的好地方。

希望这会有所帮助。

谢谢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.