如何编写Python模块/包?

本文翻译自:How to write a Python module/package?

I've been making Python scripts for simple tasks at work and never really bothered packaging them for others to use. 我一直在为工作中的简单任务制作Python脚本,从来没有真正打扰包装它们以供其他人使用。 Now I have been assigned to make a Python wrapper for a REST API. 现在我被分配为REST API创建一个Python包装器。 I have absolutely no idea on how to start and I need help. 我完全不知道如何开始,我需要帮助。

What I have: 是)我有的:

(Just want to be specific as possible) I have the virtualenv ready, it's also up in github , the .gitignore file for python is there as well, plus, the requests library for interacting with the REST API. (只是想尽可能具体)我已经准备好了virtualenv ,它也在github中 ,python的.gitignore文件也是,还有用于与REST API交互的请求库 That's it. 而已。

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模块的一般步骤。


#1楼

参考:https://stackoom.com/question/144Qd/如何编写Python模块-包


#2楼

A module is a file containing Python definitions and statements. 模块是包含Python定义和语句的文件。 The file name is the module name with the suffix .py 文件名是带有后缀.py的模块名称

create hello.py then 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 .py files put them in a folder. 要将许多.py文件分组,请将它们放在一个文件夹中。 Any folder with an __init__.py is considered a module by python and you can call them a package 具有__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. 有关更多信息,请参见6.4。 Packages . 包裹


#3楼

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. 模块:模块是包含Python定义和语句的文件。 The file name is the module name with the suffix .py appended. 文件名是附加后缀.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.py contains 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 myfunc in 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”. :包是一种使用“点模块名称”构造Python模块命名空间的方法。 For example, the module name AB 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. 例如,模块名称AB在名为A的包中指定名为B的子模块。就像使用模块保存不同模块的作者不必担心彼此的全局变量名一样,使用点模块名称可以保存作者NumPy或Python Imaging Library等多模块软件包不必担心彼此的模块名称。

Package Example : Let's now assume we have the following folder and files. 包示例 :现在假设我们有以下文件夹和文件。 Here, mymodule.py is identical to before, and __init__.py is 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. 需要__init__.py文件才能使Python将目录视为包含包。 For further information, please see the Modules documentation link provided later on. 有关详细信息,请参阅稍后提供的模块文档链接。

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.py containing the required function myfunc in 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包也应该有简短的全小写名称,但不鼓励使用下划线。


#4楼

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()

#5楼

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? 请参阅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? 对于Python 2.x - 我猜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 2,但我使用的是Python 3)


#6楼

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 setuptools and twine . 这是一个绝对最小的例子,显示了使用setuptoolstwine准备和上传包到PyPI的基本步骤。

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 setuptools for 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.py would 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='benjamin.gerfelder@gmail.com',
    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' ,我们在项目中包含一个副本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.py from 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 twine for the upload process: 由于我们不希望通过实验污染实时存储库,因此我们为测试存储库创建了一个帐户,并为上载过程安装了twine

pip install twine

Now we're almost there, with our account created we simply tell twine to 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 tutorial for more in-depth explanation. 正如我之前所说,它还有很多内容,所以请继续阅读本教程以获得更深入的解释。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值