如何编写 Python 模块/包?

2025-01-21 09:01:00
admin
原创
79
摘要:问题描述:我一直在为工作中的简单任务编写 Python 脚本,但从未真正费心将它们打包供其他人使用。现在我被指派为 REST API 编写 Python 包装器。我完全不知道如何开始,我需要帮助。我所拥有的:(只是想尽可能具体)我已经准备好了虚拟环境,它也在github 上,python 的 .gitigno...

问题描述:

我一直在为工作中的简单任务编写 Python 脚本,但从未真正费心将它们打包供其他人使用。现在我被指派为 REST API 编写 Python 包装器。我完全不知道如何开始,我需要帮助。

我所拥有的:

(只是想尽可能具体)我已经准备好了虚拟环境,它也在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 模块的通用分步过程。


解决方案 1:

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

创建hello.py然后写入以下函数作为其内容:

def helloworld():
   print("hello")

然后您可以导入hello

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

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

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

您可以按照通常的方式处理模块上的导入语句。

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

解决方案 2:

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 包名称也应简短,且全部小写,但不鼓励使用下划线。

解决方案 3:

由于还没有人回答 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

我们可以看到,基本流程并不复杂。正如我之前所说,这里介绍的内容远远不够,所以请继续阅读本教程以获得更深入的解释。

解决方案 4:

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

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

解决方案 5:

您可以创建pkg包含__init__.py(空文件)的包,file.py如下所示。 *__init__.py根据文档在“一个简单的项目”中所述,每个包都应该是空的,您可以看到我的回答,解释了 Python 中模块和包之间的区别,还可以看到我的回答,解释了如何为TestPyPI和PyPI创建、上传和安装包:

test
 |-pkg # Here
 |  |-__init__.py
 |  └-file.py
 └-main.py

并且,file.py有以下代码:

# "pkg/file..py"

PI = 3.14

def hello():
    return "Hello"

class Person:
    def __init__(self, name):
        self.name = name

现在,您可以导入代码pkg/file.py并使用它,如下所示:

# "main.py"

from pkg.file import PI, hello, Person

print(PI) # 3.14
print(hello()) # Hello
p = Person("John")
print(p.name) # John

pkg包中,您创建sub_pkg包含__init__.py(空文件)的包,sub_file.py如下所示:

test
 |-pkg
 |  |-__init__.py
 |  |-file.py
 |  └-sub_pkg # Here
 |     |-__init__.py
 |     └-sub_file.py
 └-main.py

并且,sub_file.py有以下代码:

# "pkg/sub_pkg/sub_file.py"

GRAVITY = 9.8

def world():
    return "World"

class Animal:
    def __init__(self, name):
        self.name = name

现在,您可以导入代码pkg/sub_pkg/sub_file.py并使用它,如下所示:

# "main.py"

from pkg.sub_pkg.sub_file import GRAVITY, world, Animal

print(GRAVITY) # 9.8
print(world()) # World
a = Animal("Dog")
print(a.name) # Dog

解决方案 6:

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

解决方案 7:

我的算法如下:

  1. 为你的图书馆选择一个名字——检查它是否在pypi.org上还没有被使用

  2. 创建GitHub存储库

  3. 在本地克隆仓库

  4. 添加代码src/[PACKAGE_NAME]

  5. 添加pyproject.toml并填写必填部分

  6. 添加README.md

  7. 提交并推送代码及其他文件至仓库

  8. 在终端中安装 Poetry

pip install poetry
  1. 如果你还没有 pypi.org 账户——请注册

  2. 在 pypi.org 上生成 API 令牌:帐户设置-> API 令牌 -> 添加 API 令牌

  3. 将 API 令牌添加到 Poetry 配置

poetry config pypi-token.pypi [YOUR_PYPI_API_TOKEN]
cd [REPO_FOLDER]
poetry build
poetry publish
  1. 查看你的包是否出现在 pypi.org 上

我还制作了一个分步视频来演示这个过程

解决方案 8:

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

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

def helloworld():
   print "hello"

然后你可以

import hello
hello.helloworld()

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

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

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用