如何编写一个Python模块?
我一直在为在工作中的简单任务制作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文件放在哪里,如果我做了。
我想做什么:
使一个Python模块安装与“点安装…”
如果可能的话,我需要一个一步一步的编写Python模块的过程。
一个模块是一个包含Python定义和语句的文件。 文件名是带有后缀.py
的模块名称
创buildhello.py
然后写下面的函数作为它的内容:
def helloworld(): print "hello"
那么你可以导入hello
:
>>> import hello >>> hello.helloworld() 'hello' >>>
将许多.py
文件放在一个文件夹中。 任何具有__init__.py
文件夹都被python视为模块,您可以将它们称为包
|-HelloModule |_ __init__.py |_ hellomodule.py
通常情况下,您可以使用模块上的import语句。
有关更多信息,请参见6.4。 软件包 。
Python 3 – 2015年11月18日更新
find接受的答案是有用的,但希望根据我自己的经验,为了他人的利益扩大几点。
模块:模块是一个包含Python定义和语句的文件。 文件名是带有后缀.py的模块名称。
模块示例 :假设我们在当前目录中有一个单独的python脚本,在这里我称之为mymodule.py
文件mymodule.py包含以下代码:
def myfunc(): print("Hello!")
如果我们从当前目录运行python3解释器,我们可以通过以下不同的方式导入并运行myfunc函数(通常您只需select下列选项之一):
>>> import mymodule >>> mymodule.myfunc() Hello! >>> from mymodule import myfunc >>> myfunc() Hello! >>> from mymodule import * >>> myfunc() Hello!
好吧,这很容易。
现在假设你需要把这个模块放到它自己的专用文件夹中来提供一个模块名字空间,而不是从当前的工作目录临时运行它。 这是值得解释一个包的概念的地方。
包 :包是通过使用“虚线模块名称”来构造Python模块名称空间的一种方法。 例如,模块名称AB在名为A的包中指定名为B的子模块。就像模块的使用一样,不同模块的作者不必担心彼此的全局variables名称,使用虚线模块名称可以节省作者像NumPy或Python Imaging Library这样的多模块软件包不必担心彼此的模块名称。
包示例 :现在假设我们有以下文件夹和文件。 这里mymodule.py与之前是一样的, __init__.py是一个空文件:
. └── mypackage ├── __init__.py └── mymodule.py
需要使用__init__.py文件才能使Python将目录视为包含。 有关更多信息,请参阅稍后提供的模块文档链接。
我们目前的工作目录比普通文件夹mypackage高一级
$ ls mypackage
如果我们现在运行python3解释器,我们可以通过以下不同的方式导入和运行包含所需函数myfunc的模块mymodule.py (通常只需select以下选项之一):
>>> 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中给出 – 请参阅封装和模块名称
模块应该有简短的,全小写的名字。 如果提高可读性,则可以在模块名称中使用下划线。 尽pipe不build议使用下划线,Python包也应该有简短的全小写名称。
一旦你已经定义了你select的命令,你可以简单地将保存的文件拖放到你的python程序文件的Lib文件夹中。
>>> import mymodule >>> mymodule.myfunc()
创build一个名为“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)
既然没有人涵盖OP的这个问题,
我想做什么:
使一个Python模块安装与“点安装…”
这里是一个绝对简单的例子,展示了使用setuptools
和twine
准备和上传你的包到PyPI的基本步骤。
这至less不能代替阅读教程 ,这个基本的例子还有很多。
创build包本身已经被其他答案覆盖了,所以让我们假设我们已经包括了这个步骤,并且我们的项目结构如下所示:
. └── hellostackoverflow/ ├── __init__.py └── hellostackoverflow.py
为了使用setuptools
进行打包,我们需要添加一个setup.py
文件,这将进入我们项目的根文件夹:
. ├── setup.py └── hellostackoverflow/ ├── __init__.py └── hellostackoverflow.py
至less,我们为我们的包指定元数据,我们的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
文件中包含一个副本,并在LICENCE.txt
中包含reStructuredText中的自述文件:
. ├── LICENCE.txt ├── README.rst ├── setup.py └── hellostackoverflow/ ├── __init__.py └── hellostackoverflow.py
在这一点上,我们准备开始使用setuptools
,如果我们没有安装它,我们可以用pip
来安装它:
pip install setuptools
为了做到这一点,并创build一个source distribution
,在我们的项目根文件夹,我们从命令行调用我们的setup.py
,指定我们想要sdist
:
python setup.py sdist
这将创build我们的分发包和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解释器,我会在项目目录之外的某个地方说出来,以避免混淆,并尝试使用我们shiny的新包:
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存储库创build了一个帐户,并为上传过程安装了twine
:
pip install twine
现在我们已经差不多了,创build了我们的账户,我们简单地告诉twine
上传我们的软件包,它会要求我们的凭据,并上传我们的软件包到指定的仓库:
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
我们现在可以在PyPItesting仓库login我们的账户,并惊叹我们刚刚上传的软件包一段时间,然后使用pip
抓取它:
pip install --index-url https://test.pypi.org/simple/ hellostackoverflow
我们可以看到,基本的过程并不复杂。 正如我刚才所说,除此之外,还有很多内容,所以请继续阅读教程,以获得更深入的解释。