Maison  >  Article  >  développement back-end  >  Bibliothèques Python : un guide complet sur l'écriture, l'empaquetage et la distribution

Bibliothèques Python : un guide complet sur l'écriture, l'empaquetage et la distribution

WBOY
WBOYoriginal
2023-09-03 17:37:01959parcourir

Python est un excellent langage de programmation, mais le packaging est l'un de ses points faibles. C'est un fait bien connu dans la société. Le processus d'installation, d'importation, d'utilisation et de création de packages s'est beaucoup amélioré au fil des ans, mais il n'est toujours pas comparable aux langages plus récents comme Go et Rust, qui ont beaucoup appris des difficultés de Python et d'autres langages matures. langues.

Dans ce tutoriel, vous apprendrez tout ce que vous devez savoir sur la rédaction, l'emballage et la distribution de vos propres packages.

Comment écrire une bibliothèque Python

Une bibliothèque Python est une collection cohérente de modules Python organisés en packages Python. De manière générale, cela signifie que tous les modules se trouvent dans le même répertoire et que ce répertoire se trouve sur le chemin de recherche Python.

Écrivons rapidement un petit package Python 3 et illustrons tous ces concepts.

Kit Pathologie

Python 3 est une énorme amélioration avec un excellent module Path 对象,这相对于 Python 2 笨拙的 os.path. Mais il manque une fonctionnalité clé : trouver le chemin d’accès au script actuel. Ceci est important lorsque vous souhaitez positionner les fichiers d'accès par rapport au script actuel.

Dans de nombreux cas, le script peut être installé n'importe où, donc les chemins absolus ne peuvent pas être utilisés, et le répertoire de travail peut être défini sur n'importe quelle valeur, donc les chemins relatifs ne peuvent pas être utilisés. Si vous souhaitez accéder aux fichiers d'un sous-répertoire ou d'un répertoire parent, vous devez pouvoir connaître le répertoire de script actuel.

Voici comment procéder en Python :

import pathlib

script_dir = pathlib.Path(__file__).parent.resolve()

Pour accéder à un fichier nommé "file.txt" dans le sous-répertoire "data" du répertoire de script actuel, vous pouvez utiliser le code suivant : print(open(str(script_dir/' data/file.txt').read())

Avec le package pathologie, vous disposez d'une méthode script_dir intégrée que vous pouvez utiliser comme ceci :

from pathology.Path import script_dir

print(open(str(script_dir()/'data/file.txt').read())

Oui, c’est un peu difficile à prononcer. Le forfait pathologie est très simple. Il dérive sa propre classe Path du Path de pathlib et ajoute un script_dir() statique qui renvoie toujours le chemin du script appelant.

Voici la mise en œuvre :

import pathlib
import inspect

class Path(type(pathlib.Path())):
    @staticmethod
    def script_dir():
        print(inspect.stack()[1].filename)
        p = pathlib.Path(inspect.stack()[1].filename)
        return p.parent.resolve()

En raison de l'implémentation multiplateforme de pathlib.Path, vous pouvez en dériver directement et devez dériver d'une sous-classe spécifique (PosixPathou pathlib.Path的跨平台实现,您可以直接从它派生,并且必须从特定子类派生(PosixPath or WindowsPath)。 script_dir

WindowsPath). L'analyse <code>script_dir utilise des modules d'inspection pour trouver l'appelant et ses attributs de nom de fichier.

Test de pathologie

Chaque fois que vous écrivez quelque chose de plus qu'un script ponctuel, vous devriez le tester. Le module de pathologie ne fait pas exception. Voici les tests utilisant le framework de tests unitaires standard :

import os
import shutil 
from unittest import TestCase
from pathology.path import Path


class PathTest(TestCase):
    def test_script_dir(self):
        expected = os.path.abspath(os.path.dirname(__file__))
        actual = str(Path.script_dir())
        self.assertEqual(expected, actual)

    def test_file_access(self):
        script_dir = os.path.abspath(os.path.dirname(__file__))
        subdir = os.path.join(script_dir, 'test_data')
        if Path(subdir).is_dir():
            shutil.rmtree(subdir)
        os.makedirs(subdir)
        file_path = str(Path(subdir)/'file.txt')
        content = '123'
        open(file_path, 'w').write(content)
        test_path = Path.script_dir()/subdir/'file.txt'
        actual = open(str(test_path)).read()

        self.assertEqual(content, actual)

Chemin Python

sys.path 中可用。这是我当前的 sys.pathLes packages Python doivent être installés quelque part sur le chemin de recherche Python pour pouvoir être importés par les modules Python. Le chemin de recherche Python est une liste de répertoires et se trouve toujours à l'adresse

 :

>>> print('\n'.join(sys.path))

/Users/gigi.sayfan/miniconda3/envs/py3/lib/python36.zip
/Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6
/Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/lib-dynload
/Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/site-packages
/Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/site-packages/setuptools-27.2.0-py3.6.egg 

Notez que la première ligne vide de la sortie représente le répertoire actuel, vous pouvez donc importer des modules depuis le répertoire de travail actuel, quel qu'il soit. Vous pouvez ajouter ou supprimer des répertoires directement dans sys.path.

PYTHONPATH 环境变量,还有一些其他方法可以控制它。默认情况下包含标准 site-packagesVous pouvez également définir un

qui est l'emplacement où vous installez les packages via pip go.

Comment empaqueter les bibliothèques Python

Maintenant que nous avons le code et les tests, regroupons le tout dans la bibliothèque appropriée. Python fournit un moyen simple d'accéder au module de configuration. Vous créez un fichier appelé setup.py

dans le répertoire racine de votre package.

Le fichier setup.pypackages 项的补充,该项使用从 setuptools 导入的 find_packages() contient de nombreuses informations de métadonnées telles que l'auteur, la licence, le responsable et d'autres informations sur le package. Il s'agit d'une paire de

fonctions pour trouver des sous-packages.

Voici le fichier setup.py

du package pathologie :

from setuptools import setup, find_packages

setup(name='pathology',
      version='0.1',
      url='https://github.com/the-gigi/pathology',
      license='MIT',
      author='Gigi Sayfan',
      author_email='the.gigi@gmail.com',
      description='Add static script_dir() method to Path',
      packages=find_packages(exclude=['tests']),
      long_description=open('README.md').read(),
      zip_safe=False)

Pack de distribution source

Une distribution source est une archive contenant des packages Python, des modules et d'autres fichiers utilisés pour la distribution de packages (par exemple, version 1, version 2, etc.). Une fois le fichier distribué, les utilisateurs finaux peuvent le télécharger et l'installer sur leur système d'exploitation.

python setup.py sdistPour créer un package de distribution source (sdist), exécutez :

Construisons une distribution de code source :

$ python setup.py sdist
running sdist
running egg_info
creating pathology.egg-info
writing pathology.egg-info/PKG-INFO
writing dependency_links to pathology.egg-info/dependency_links.txt
writing top-level names to pathology.egg-info/top_level.txt
writing manifest file 'pathology.egg-info/SOURCES.txt'
reading manifest file 'pathology.egg-info/SOURCES.txt'
writing manifest file 'pathology.egg-info/SOURCES.txt'
warning: sdist: standard file not found: should have one of README, README.rst, README.txt

running check
creating pathology-0.1
creating pathology-0.1/pathology
creating pathology-0.1/pathology.egg-info
copying files to pathology-0.1...
copying setup.py -> pathology-0.1
copying pathology/__init__.py -> pathology-0.1/pathology
copying pathology/path.py -> pathology-0.1/pathology
copying pathology.egg-info/PKG-INFO -> pathology-0.1/pathology.egg-info
copying pathology.egg-info/SOURCES.txt -> pathology-0.1/pathology.egg-info
copying pathology.egg-info/dependency_links.txt -> pathology-0.1/pathology.egg-info
copying pathology.egg-info/not-zip-safe -> pathology-0.1/pathology.egg-info
copying pathology.egg-info/top_level.txt -> pathology-0.1/pathology.egg-info
Writing pathology-0.1/setup.cfg
creating dist
Creating tar archive
removing 'pathology-0.1' (and everything under it)
Cet avertissement est dû au fait que j'ai utilisé un fichier README.md non standard. Il est prudent de l'ignorer. La commande ci-dessus créera un fichier d'archive au format par défaut du système d'exploitation actuel. Pour les systèmes Unix, un fichier tar gzippé sera généré dans le répertoire dist

 :

$ ls -la dist
total 8
drwxr-xr-x   3 gigi.sayfan  gigi.sayfan   102 Apr 18 21:20 .
drwxr-xr-x  12 gigi.sayfan  gigi.sayfan   408 Apr 18 21:20 ..
-rw-r--r--   1 gigi.sayfan  gigi.sayfan  1223 Apr 18 21:20 pathology-0.1.tar.gz

Si vous utilisez Windows, un fichier zip sera généré.

Vous pouvez également spécifier d'autres formats de fichiers supplémentaires à l'aide des options de format indiquées ci-dessous. 🎜
python setup.py sdist --formats=gztar,zip

例如,上述命令将生成一个 gzip 压缩的 tarball 和一个 zip 文件。

可用的不同格式有:

  • zip: .zip
  • gztar: .tar.gz
  • bztar: .tar.bz2
  • xztar: .tar.xz
  • ztar: .tar.Z
  • tar: .tar

二进制分发

要创建一个名为“wheel”的二进制发行版,请运行: python setup.py bdist_wheel

这是一个二进制发行版:

$ python setup.py bdist_wheel
running bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/pathology
copying pathology/__init__.py -> build/lib/pathology
copying pathology/path.py -> build/lib/pathology
installing to build/bdist.macosx-10.7-x86_64/wheel
running install
running install_lib
creating build/bdist.macosx-10.7-x86_64
creating build/bdist.macosx-10.7-x86_64/wheel
creating build/bdist.macosx-10.7-x86_64/wheel/pathology
copying build/lib/pathology/__init__.py -> build/bdist.macosx-10.7-x86_64/wheel/pathology
copying build/lib/pathology/path.py -> build/bdist.macosx-10.7-x86_64/wheel/pathology
running install_egg_info
running egg_info
writing pathology.egg-info/PKG-INFO
writing dependency_links to pathology.egg-info/dependency_links.txt
writing top-level names to pathology.egg-info/top_level.txt
reading manifest file 'pathology.egg-info/SOURCES.txt'
writing manifest file 'pathology.egg-info/SOURCES.txt'
Copying pathology.egg-info to build/bdist.macosx-10.7-x86_64/wheel/pathology-0.1-py3.6.egg-info
running install_scripts
creating build/bdist.macosx-10.7-x86_64/wheel/pathology-0.1.dist-info/WHEEL

病理包仅包含纯Python模块,因此可以构建通用包。如果您的软件包包含 C 扩展,则必须为每个平台构建单独的轮子:

$ ls -la dist
total 16
drwxr-xr-x   4 gigi.sayfan  gigi.sayfan   136 Apr 18 21:24 .
drwxr-xr-x  13 gigi.sayfan  gigi.sayfan   442 Apr 18 21:24 ..
-rw-r--r--   1 gigi.sayfan  gigi.sayfan  2695 Apr 18 21:24 pathology-0.1-py3-none-any.whl
-rw-r--r--   1 gigi.sayfan  gigi.sayfan  1223 Apr 18 21:20 pathology-0.1.tar.gz

要更深入地了解打包 Python 库的主题,请查看如何编写您自己的 Python 包。

如何分发 Python 包

Python 有一个名为 PyPI(Python 包索引)的中央包存储库。 PyPI 可以轻松管理不同版本的包。例如,如果用户需要安装特定的软件包版本,pip 知道在哪里查找它。

当您使用 pip 安装 Python 包时,它将从 PyPI 下载该包(除非您指定不同的存储库)。为了分发我们的病理包,我们需要将其上传到 PyPI 并提供 PyPI 所需的一些额外元数据。步骤是:

  • 升级您的 pip 版本。
  • 在 PyPI 上创建一个帐户(只需一次)。
  • 注册您的包裹。
  • 上传您的包。

升级您的 pip 版本

确保您的操作系统中安装了最新版本的 pip。要升级 pip,请发出以下命令

python3 -m pip install --upgrade pip

创建帐户

您可以在 PyPI 网站上创建帐户。然后在您的主目录中创建一个 .pypirc 文件:

[distutils] 
index-servers=pypi
 
[pypi]
repository = https://pypi.python.org/pypi
username = the_gigi

出于测试目的,您可以将 pypitest 索引服务器添加到您的 .pypirc 文件中:

[distutils]
index-servers=
    pypi
    pypitest

[pypitest]
repository = https://testpypi.python.org/pypi
username = the_gigi

[pypi]
repository = https://pypi.python.org/pypi
username = the_gigi

注册您的包裹

如果这是您的软件包的第一个版本,您需要使用 PyPI 注册它。使用setup.py的注册命令。它会询问您的密码。请注意,我将其指向此处的测试存储库:

$ python setup.py register -r pypitest
running register
running egg_info
writing pathology.egg-info/PKG-INFO
writing dependency_links to pathology.egg-info/dependency_links.txt
writing top-level names to pathology.egg-info/top_level.txt
reading manifest file 'pathology.egg-info/SOURCES.txt'
writing manifest file 'pathology.egg-info/SOURCES.txt'
running check
Password:
Registering pathology to https://testpypi.python.org/pypi
Server response (200): OK

上传您的包

现在包已注册,我们可以上传它了。我建议使用麻线,这样更安全。像往常一样使用 pip install twine 安装它。然后使用 twine 上传您的包并提供您的密码(在下面进行编辑):

$ twine upload -r pypitest -p <redacted> dist/*
Uploading distributions to https://testpypi.python.org/pypi
Uploading pathology-0.1-py3-none-any.whl
[================================] 5679/5679 - 00:00:02
Uploading pathology-0.1.tar.gz
[================================] 4185/4185 - 00:00:01 

该软件包现已在 PyPI 官方网站上提供,如下所示。

Python 库:编写、打包和分发的综合指南

要使用 pip 安装它,只需发出以下命令:

pip install pathology

要更深入地了解分发包的主题,请查看如何共享您的 Python 包。

结论

在本教程中,我们完成了编写 Python 库、打包并通过 PyPI 分发它的完整过程。此时,您应该拥有编写库并与世界共享库的所有工具。

本文已根据 Esther Vaati 的贡献进行了更新。 Esther 是 Envato Tuts+ 的软件开发人员和作家。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn