如何编写 Python 模块/包?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15746675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write a Python module/package?
提问by yowmamasita
I've been making Python scripts for simple tasks at work and never really bothered packaging them for others to use. Now I have been assigned to make a Python wrapper for a REST API. I have absolutely no idea on how to start and I need help.
我一直在为工作中的简单任务制作 Python 脚本,从来没有真正打扰过将它们打包以供其他人使用。现在我被指派为 REST API 制作一个 Python 包装器。我完全不知道如何开始,我需要帮助。
What I have:
我拥有的:
(Just want to be specific as possible) I have the virtualenvready, it's also up in github, the .gitignore file for python is there as well, plus, the requests libraryfor interacting with the REST API. That's it.
(只是想尽可能具体)我已经准备好了virtualenv,它也在github 中,python 的 .gitignore 文件也在那里,另外还有用于与 REST API 交互的请求库。就是这样。
Here's the current directory tree
这是当前的目录树
.
├── bin
│?? └── /the usual stuff/
├── include
│?? └── /the usual stuff/
├── lib
│?? └── python2.7
│?? └── /the usual stuff/
├── local
│?? └── /the usual stuff/
└── README.md
27 directories, 280 files
I don't even know where to put the .py files, if I ever make one.
我什至不知道把 .py 文件放在哪里,如果我做过的话。
What I wanted to do:
我想做的事情:
Make a python module install-able with "pip install ..."
使用“pip install ...”使python模块可安装
If possible, I want a general step by step process on writing Python modules.
如果可能的话,我想要一个关于编写 Python 模块的一般分步过程。
采纳答案by Anuj
A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py
模块是包含 Python 定义和语句的文件。文件名是带有后缀的模块名.py
create hello.pythen write the following function as its content:
创建hello.py然后编写以下函数作为其内容:
def helloworld():
print "hello"
Then you can import hello:
然后你可以导入hello:
>>> import hello
>>> hello.helloworld()
'hello'
>>>
To group many .pyfiles put them in a folder. Any folder with an __init__.pyis considered a module by python and you can call them a package
要将多个.py文件分组,请将它们放在一个文件夹中。任何带有 的文件夹__init__.py都被python视为模块,您可以将它们称为包
|-HelloModule
|_ __init__.py
|_ hellomodule.py
You can go about with the import statement on your module the usual way.
您可以按照通常的方式在模块上使用 import 语句。
For more information, see 6.4. Packages.
有关更多信息,请参见6.4。包。
回答by arcseldon
Python 3 - UPDATED 18th November 2015
Python 3 - 2015 年 11 月 18 日更新
Found the accepted answer useful, yet wished to expand on several points for the benefit of others based on my own experiences.
发现接受的答案很有用,但希望根据我自己的经验扩展几点以造福他人。
Module:A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended.
模块:模块是包含 Python 定义和语句的文件。文件名是后缀 .py 的模块名称。
Module Example: Assume we have a single python script in the current directory, here I am calling it mymodule.py
模块示例:假设我们在当前目录中有一个 python 脚本,这里我称之为mymodule.py
The file mymodule.pycontains the following code:
文件mymodule.py包含以下代码:
def myfunc():
print("Hello!")
If we run the python3 interpreter from the current directory, we can import and run the function myfuncin the following different ways (you would typically just choose one of the following):
如果我们从当前目录运行 python3 解释器,我们可以通过以下不同的方式导入和运行函数myfunc(您通常只需选择以下其中一种):
>>> import mymodule
>>> mymodule.myfunc()
Hello!
>>> from mymodule import myfunc
>>> myfunc()
Hello!
>>> from mymodule import *
>>> myfunc()
Hello!
Ok, so that was easy enough.
好的,这很容易。
Now assume you have the need to put this module into its own dedicated folder to provide a module namespace, instead of just running it ad-hoc from the current working directory. This is where it is worth explaining the concept of a package.
现在假设您需要将此模块放入其自己的专用文件夹中以提供模块命名空间,而不是仅从当前工作目录临时运行它。这是值得解释包概念的地方。
Package: Packages are a way of structuring Python's module namespace by using “dotted module names”. For example, the module name A.B designates a submodule named B in a package named A. Just like the use of modules saves the authors of different modules from having to worry about each other's global variable names, the use of dotted module names saves the authors of multi-module packages like NumPy or the Python Imaging Library from having to worry about each other's module names.
包:包是一种通过使用“带点的模块名称”来构建 Python 模块命名空间的方法。例如,模块名AB 指定了一个名为A 的包中名为B 的子模块。就像使用modules 使不同模块的作者不必担心彼此的全局变量名一样,使用带点的模块名可以节省作者NumPy 或 Python Imaging Library 等多模块包,而不必担心彼此的模块名称。
Package Example: Let's now assume we have the following folder and files. Here, mymodule.pyis identical to before, and __init__.pyis an empty file:
包示例:现在假设我们有以下文件夹和文件。这里,mymodule.py与之前相同,而__init__.py是一个空文件:
.
└── mypackage
├── __init__.py
└── mymodule.py
The __init__.py files are required to make Python treat the directories as containing packages. For further information, please see the Modules documentation link provided later on.
需要 __init__.py 文件才能使 Python 将目录视为包含包。有关更多信息,请参阅稍后提供的模块文档链接。
Our current working directory is one level above the ordinary folder called mypackage
我们当前的工作目录比普通文件夹mypackage 高一级
$ ls
mypackage
If we run the python3 interpreter now, we can import and run the module mymodule.pycontaining the required function myfuncin the following different ways (you would typically just choose one of the following):
如果我们现在运行 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!
Assuming Python 3, there is excellent documentation at: Modules
假设 Python 3,有很好的文档:模块
In terms of naming conventions for packages and modules, the general guidelines are given in PEP-0008 - please see Package and Module Names
在包和模块的命名约定方面,PEP-0008 中给出了一般准则 - 请参阅包和模块名称
Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability. Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.
模块应该有简短的全小写名称。如果可以提高可读性,可以在模块名称中使用下划线。Python 包也应该有简短的、全小写的名称,但不鼓励使用下划线。
回答by Dreamatronix
Once you have defined your chosen commands, you can simply drag and drop the saved file into the Lib folder in your python program files.
一旦你定义了你选择的命令,你可以简单地将保存的文件拖放到 python 程序文件的 Lib 文件夹中。
>>> import mymodule
>>> mymodule.myfunc()
回答by Kakkoiikun
Make a file named "hello.py"
制作一个名为“hello.py”的文件
If you are using Python 2.x
如果您使用的是 Python 2.x
def func():
print "Hello"
If you are using Python 3.x
如果您使用的是 Python 3.x
def func():
print("Hello")
Run the file. Then, you can try the following:
运行文件。然后,您可以尝试以下操作:
>>> import hello
>>> hello.func()
Hello
If you want a little bit hard, you can use the following:
如果你想要一点点困难,你可以使用以下方法:
If you are using Python 2.x
如果您使用的是 Python 2.x
def say(text):
print text
If you are using Python 3.x
如果您使用的是 Python 3.x
def say(text):
print(text)
See the one on the parenthesis beside the define? That is important. It is the one that you can use within the define.
看到定义旁边括号中的那个了吗?这很重要。它是您可以在定义中使用的那个。
Text - You can use it when you want the program to say what you want. According to its name, it is text. I hope you know what text means. It means "words" or "sentences".
文本 - 当您希望程序说出您想要的内容时,您可以使用它。顾名思义,就是文字。我希望你知道文本是什么意思。它的意思是“单词”或“句子”。
Run the file. Then, you can try the following if you are using Python 3.x:
运行文件。然后,如果您使用的是 Python 3.x,则可以尝试以下操作:
>>> import hello
>>> hello.say("hi")
hi
>>> from hello import say
>>> say("test")
test
For Python 2.x - I guess same thing with Python 3? No idea. Correct me if I made a mistake on Python 2.x (I know Python 2 but I am used with Python 3)
对于 Python 2.x - 我猜 Python 3 也是一样?不知道。如果我在 Python 2.x 上犯了错误,请纠正我(我知道 Python 2,但我使用 Python 3)
回答by bgse
Since nobody did cover this question of the OP yet:
由于没有人确实涵盖了 OP 的这个问题:
What I wanted to do:
Make a python module install-able with "pip install ..."
我想做的事情:
使用“pip install ...”使python模块可安装
Here is an absolute minimal example, showing the basic steps of preparing and uploading your package to PyPI using setuptoolsand twine.
这是一个绝对最小的示例,显示了使用setuptools和准备包并将其上传到 PyPI 的基本步骤twine。
This is by no means a substitute for reading at least the tutorial, there is much more to it than covered in this very basic example.
这绝不是阅读至少教程的替代品,除了这个非常基本的示例中涵盖的内容之外,还有更多内容。
Creating the package itself is already covered by other answers here, so let us assume we have that step covered and our project structure like this:
此处的其他答案已经涵盖了创建包本身,因此让我们假设我们已经涵盖了该步骤,并且我们的项目结构如下所示:
.
└── hellostackoverflow/
├── __init__.py
└── hellostackoverflow.py
In order to use setuptoolsfor packaging, we need to add a file setup.py, this goes into the root folder of our project:
为了setuptools用于打包,我们需要添加一个文件setup.py,它进入我们项目的根文件夹:
.
├── setup.py
└── hellostackoverflow/
├── __init__.py
└── hellostackoverflow.py
At the minimum, we specify the metadata for our package, our setup.pywould look like this:
至少,我们为我们的包指定元数据,我们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='[email protected]',
keywords=['example'],
url='https://github.com/bgse/hellostackoverflow'
)
Since we have set license='MIT', we include a copy in our project as LICENCE.txt, alongside a readme file in reStructuredText as README.rst:
由于我们已经设置了license='MIT',我们在我们的项目中包含了一个副本 as LICENCE.txt,以及 reStructuredText 中的一个自述文件README.rst:
.
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
├── __init__.py
└── hellostackoverflow.py
At this point, we are ready to go to start packaging using setuptools, if we do not have it already installed, we can install it with pip:
此时,我们准备开始使用 打包setuptools,如果我们还没有安装它,我们可以使用以下命令安装它pip:
pip install setuptools
In order to do that and create a source distribution, at our project root folder we call our setup.pyfrom the command line, specifying we want sdist:
为了做到这一点并source distribution在我们的项目根文件夹中创建一个,我们setup.py从命令行调用我们的,指定我们想要sdist:
python setup.py sdist
This will create our distribution package and egg-info, and result in a folder structure like this, with our package in dist:
这将创建我们的分发包和egg-info,并产生这样的文件夹结构,我们的包在dist:
.
├── dist/
├── hellostackoverflow.egg-info/
├── LICENCE.txt
├── README.rst
├── setup.py
└── hellostackoverflow/
├── __init__.py
└── hellostackoverflow.py
At this point, we have a package we can install using pip, so from our project root (assuming you have all the naming like in this example):
此时,我们有一个可以使用 安装的包pip,因此从我们的项目根目录(假设您具有本示例中的所有命名):
pip install ./dist/hellostackoverflow-0.0.1.tar.gz
If all goes well, we can now open a Python interpreter, I would say somewhere outside our project directory to avoid any confusion, and try to use our shiny new package:
如果一切顺利,我们现在可以打开一个 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!'
Now that we have confirmed the package installs and works, we can upload it to PyPI.
现在我们已经确认包安装和工作,我们可以将它上传到 PyPI。
Since we do not want to pollute the live repository with our experiments, we create an account for the testing repository, and install twinefor the upload process:
由于我们不想用我们的实验污染实时存储库,我们为测试存储库创建一个帐户,并twine为上传过程安装:
pip install twine
Now we're almost there, with our account created we simply tell twineto upload our package, it will ask for our credentials and upload our package to the specified repository:
现在我们快到了,创建我们的帐户后,我们只需告诉twine上传我们的包,它会询问我们的凭据并将我们的包上传到指定的存储库:
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
We can now log into our account on the PyPI test repository and marvel at our freshly uploaded package for a while, and then grab it using pip:
我们现在可以在 PyPI 测试存储库上登录我们的帐户并惊叹于我们新上传的包一段时间,然后使用pip以下命令获取它:
pip install --index-url https://test.pypi.org/simple/ hellostackoverflow
As we can see, the basic process is not very complicated. As I said earlier, there is a lot more to it than covered here, so go ahead and read the tutorialfor more in-depth explanation.
如我们所见,基本过程并不复杂。正如我之前所说,它比这里介绍的要多得多,所以请继续阅读教程以获得更深入的解释。
回答by MacSanhe
I created a project to easily initiate a project skeleton from scratch. https://github.com/MacHu-GWU/pygitrepo-project.
我创建了一个项目,以便从头开始轻松启动项目框架。https://github.com/MacHu-GWU/pygitrepo-project。
And you can create a test project, let's say, learn_creating_py_package.
您可以创建一个测试项目,比如说,learn_creating_py_package.
You can learn what component you should have for different purpose like:
您可以了解出于不同目的应该使用哪些组件,例如:
- create virtualenv
- install itself
- run unittest
- run code coverage
- build document
- deploy document
- run unittest in different python version
- deploy to PYPI
- 创建虚拟环境
- 自行安装
- 运行单元测试
- 运行代码覆盖率
- 构建文档
- 部署文件
- 在不同的python版本中运行unittest
- 部署到 PYPI
The advantage of using pygitrepois that those tedious are automatically created itself and adapt your package_name, project_name, github_account, document host service, windows or macos or linux.
使用的好处pygitrepo是那些繁琐的会自动创建并适应你的package_name, project_name, github_account, document host service, windows or macos or linux。
It is a good place to learn develop a python project like a pro.
这是一个像专业人士一样学习开发python项目的好地方。
Hope this could help.
希望这会有所帮助。
Thank you.
谢谢你。

