杰瑞科技汇

Python dist packages是什么?如何管理?

Of course! This is a fundamental concept in Python development and deployment. Let's break down what "dist packages" are, why they're important, and how to work with them.

Python dist packages是什么?如何管理?-图1
(图片来源网络,侵删)

What is a "Dist Package"?

In short, a dist package (short for "distribution package") is a standardized, installable unit of Python software. It's the "product" that a developer creates and that a user installs onto their system.

Think of it like an .exe or .msi file for Windows software, or a .dmg for macOS. A Python dist package is the bundle that contains your code, its dependencies, and metadata needed for the Python package manager (pip) to understand and install it correctly.

There are two main formats for dist packages:

  1. Wheel (.whl): This is the modern, recommended format. It's a ZIP archive with a specific naming convention and a .dist-info directory inside. The key advantage is that it's pre-compiled. When pip installs a wheel, it can simply unarchive it and place the files directly into the Python environment, which is very fast and reliable.
  2. Source Distribution (.tar.gz): This is a traditional format. It contains your source code (including setup files) in a gzipped tarball. When pip installs a source distribution, it has to:
    • Download and extract the archive.
    • Run a build process (often using setuptools).
    • Compile any Python code (e.g., Cython extensions) or C extensions.
    • Install the resulting files.

Why Wheels are Preferred:

Python dist packages是什么?如何管理?-图2
(图片来源网络,侵删)
  • Speed: Installation is much faster as no compilation is needed.
  • Reliability: Avoids build failures on systems without necessary compilers (like MSVC on Windows).
  • Offline Installation: Once downloaded, a wheel can be installed without an internet connection.

The Two Sides of the Coin: setup.py vs. pyproject.toml

The process of creating a dist package revolves around a "build specification." This specification tells the build tools how to find your code, what its dependencies are, and what metadata to include (like name, version, author).

There are two primary ways to define this specification:

The setup.py Approach (The "Old" Way)

This is the classic method. You create a setup.py file in the root of your project that calls functions from the setuptools library.

Example setup.py:

Python dist packages是什么?如何管理?-图3
(图片来源网络,侵删)
# setup.py
from setuptools import setup, find_packages
setup(
    name="my-awesome-package",
    version="0.1.0",
    author="Your Name",
    author_email="you@example.com",
    description="A small example package",
    long_description=open("README.md").read(),
    long_description_content_type="text/markdown",
    url="https://github.com/yourusername/my-awesome-package",
    packages=find_packages(), # Automatically finds all packages in your project
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires=">=3.8",
    install_requires=[
        'requests',  # A dependency
        'numpy>=1.20', # Another dependency with a version constraint
    ],
)

How to build with setup.py: You use a tool called build to create the dist packages from your setup.py file.

# First, install the build tool
pip install build
# Run the build command in your project's root directory
python -m build

This command will produce two files in a new dist/ directory:

  • my-awesome-package-0.1.0.tar.gz (Source Distribution)
  • my-awesome_package-0.1.0-py3-none-any.whl (Wheel)

The pyproject.toml Approach (The "Modern" Way, PEP 517/518)

This is the current best practice. Instead of imperative code in setup.py, you use a declarative configuration file called pyproject.toml. This file separates the build configuration from the project metadata, which is cleaner and more standardized.

Example pyproject.toml:

# pyproject.toml
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-awesome-package"
version = "0.1.0"
authors = [
  { name="Your Name", email="you@example.com" },
]
description = "A small example package"
readme = "README.md"
requires-python = ">=3.8"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]
dependencies = [
    "requests",
    "numpy>=1.20",
]
# Optional: Entry points for command-line scripts
[project.scripts]
my-command = "my_awesome_package.cli:main"
  • The [build-system] section tells the build tools (like pip and build) how to build your package (it uses setuptools).
  • The [project] section contains all the metadata that used to be in setup.py.

How to build with pyproject.toml: The process is exactly the same! You still use the build tool, which is smart enough to look for a pyproject.toml file.

# Make sure you have the build tool
pip install build
# Run the build command
python -m build

This will also produce the .tar.gz and .whl files in the dist/ directory.


The Complete Workflow: From Project to Installation

Here is a step-by-step guide for a modern Python project.

Project Structure

Your project should look something like this:

my-awesome-project/
├── src/
│   └── my_awesome_package/
│       ├── __init__.py
│       └── cli.py
├── pyproject.toml
├── README.md
└── LICENSE

Write Your Code

src/my_awesome_package/__init__.py

# Make the main function available when the package is imported
from .cli import main
__version__ = "0.1.0"

src/my_awesome_package/cli.py

def main():
    print("Hello from my awesome package!")

Create pyproject.toml

Use the example from above, making sure to adjust paths and details.

Build the Package

In your terminal, at the root of my-awesome-project/:

pip install build
python -m build

You'll now have a dist/ folder with your two package files.

Install Your Package Locally (for testing)

Before publishing to a repository, you can install your built package to test it. The -e flag installs it in "editable" mode, meaning changes to your source code will be reflected immediately without needing to reinstall.

# Install the wheel file you just built
pip install dist/my-awesome_package-0.1.0-py3-none-any.whl -e

Now you can run your command from anywhere:

$ my-command
Hello from my awesome package!

Upload to a Package Repository (e.g., PyPI)

Once you're ready to share your package with the world, you upload it to the Python Package Index (PyPI).

  1. Get an account on PyPI.
  2. Install twine, the standard tool for uploading:
    pip install twine
  3. Upload your files:
    twine upload dist/*

    You will be prompted for your PyPI username and password (or an API token).

After this, anyone in the world can install your package with a simple:

pip install my-awesome-package

Summary: Key Takeaways

Concept Description
Dist Package An installable unit of Python software (.whl or .tar.gz).
Wheel (.whl) The modern, pre-compiled format. Preferred for installation.
Source Dist (.tar.gz) The traditional source code format. Used for building from source.
build tool The standard tool for building dist packages from setup.py or pyproject.toml.
pyproject.toml The modern, declarative way to define project metadata and build requirements. Recommended.
setup.py The older, imperative way. Still works but is being phased out.
twine The standard tool for uploading dist packages to PyPI.
分享:
扫描分享到社交APP
上一篇
下一篇