我一直在为工作中的简单任务编写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模块的通用步骤。


模块是一个包含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。包。


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模块名称空间的一种方式。例如,模块名A.B在名为a的包中指定了名为B的子模块。就像使用模块可以使不同模块的作者不必担心彼此的全局变量名一样,使用虚线模块名可以使NumPy或Python成像库等多模块包的作者不必担心彼此的模块名。

包示例:现在假设我们有以下文件夹和文件。这里,mymodule.py与之前相同,__init__.py是一个空文件:

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

需要__init__.py文件才能使Python将这些目录视为包含包的目录。欲了解更多信息,请参阅稍后提供的Modules文档链接。

我们当前的工作目录比称为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,在:Modules中有很好的文档

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

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


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

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

创建一个名为"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)

看到define旁边括号里的那个了吗?这很重要。它是可以在define中使用的。

文本-当你想让程序说出你想要的东西时,你可以使用它。根据它的名字,它是文本。我希望你知道文字是什么意思。它的意思是“单词”或“句子”。

运行文件。然后,如果您正在使用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的这个问题:

我想做的是: 使用"pip install…"使python模块可安装

下面是一个绝对最小的示例,展示了使用setuptools和twine准备包并将其上传到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',我们在我们的项目中包含了一个副本license .txt,以及一个在reStructuredText中的自述文件readme .rst:

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

在这一点上,我们已经准备好开始使用setuptools进行打包,如果我们还没有安装它,我们可以使用pip安装它:

pip install setuptools

为了做到这一点并创建一个源代码发行版,在我们的项目根文件夹中,我们从命令行调用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

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


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

创建一个名为hello.py的文件,其内容为以下函数:

def helloworld():
   print "hello"

然后你就可以

import hello
hello.helloworld()

要对许多.py文件进行分组,请将它们放在一个文件夹中。任何带有init.py的文件夹在python中都被认为是模块,你可以称它们为包。

| -HelloModule | _ init.py | _ hellomodule.py