409

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

4

6 回答 6

449

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

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

def helloworld():
   print "hello"

然后你可以导入hello

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

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

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

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

有关详细信息,请参阅6.4。包

于 2013-04-01T16:24:12.950 回答
258

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 包也应该有简短的全小写名称,尽管不鼓励使用下划线。

于 2015-11-18T01:05:55.800 回答
223

由于还没有人讨论过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

正如我们所看到的,基本过程并不是很复杂。正如我之前所说,它的内容远不止于此,因此请继续阅读本教程以获得更深入的解释。

于 2017-11-15T01:57:40.440 回答
8

一旦你定义了你选择的命令,你可以简单地将保存的文件拖放到 python 程序文件中的 Lib 文件夹中。

>>> import mymodule 
>>> mymodule.myfunc()
于 2017-01-15T11:54:54.203 回答
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)

于 2017-05-05T09:17:55.053 回答
0

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

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

def helloworld():
   print "hello"

那么你就可以

import hello
hello.helloworld()

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

|-HelloModule |_初始化.py |_ hellomodule.py

于 2020-08-22T16:52:29.417 回答