最近在做Project的时候发现一个package无法在jump box之外的机器上通过pip安装,后来发现这是一个内部开发的python package, 并且为jump box的pip做了设置,加入了内部的package repo address/credential。关于package 的创建和发布还不是很了解,这里专门总结一下。 Python Packaging User Guide
Package and Module
Packages contains modules (module is normally a single python source file) or other packages. Modules also are objects with special attributes.
1 | ## urllib is package because it contains other modules or packages |
How does python know where to import?
1 | import sys |
Or specify in environment variable (see python --help
):
1 | ## will append to sys.path |
Package Structure
1 | package/: |
When import package, __init__.py
will be executed if it has contents, so you can have init code here.
module1.py and modul2.py are normal python source files, subpackage1 and subpackage2 are nested packages that has its own module. module1.py can import subpackage1 resources, and so on.
1 | ## absolute imports |
Note that relative import can only be used to import modules within the current top-level package and can only in the form if
from ... import
.
Sometimes you will see __all__
in __init__.py
, it control the public objects you can use when from .. import *
. If you want to import other modules or packages manually, it is fine.
Namespace Package
For splitting a single python package across multiple directories on disk.
Namespace package may not have __init__.py
.
For example, split package1 to different path: path1 and path2, 注意这里package1 top-level 没有__init__.py
.
1 | path1/ |
When import:
1 | import sys |
Executable Directory
You can execute a directory if it contains __main__.py
, then you can zip the directory and run the zip file.
1 | directory/ |
注意directory 没有__init__.py
,它不是一个package.
1 | ## it will run __main__.py |
这就相当于打包了一个executable,别人使用时就不需要安装其他依赖了。
Executable Package
if you want to execute a package, also need to adds __main__.py
, you cannot use __init__.py
since it is only executed when import.
1 | package/ |
1 | ## run it, arguments will be read by __main__.py |
Package Layout
This is the recommended structure:
1 | project_name/ |
The setup.py
for example:
1 | import setuptools |
关于tox
, 是一个方便自动化测试的工具:
tox: Automate and standardize testing in Python.
后面讲了plugins的实现 via setuptools or namespace packages. 目前没用到。
Package Distribution
When you create a virtualenv, there are pip, wheel and setuptools installed already.
There are source
and built
distrubutions, built
package can place directly into installation directory and can be platform-specific, it is a .whl
file. source
package is tar.gz file, need to build before installing it. If you run pip download
, you will see these distribution files.
For source
package:
1 | cd package |
For built
package:
1 | cd package |
Reading about what is wheel
:
https://realpython.com/python-wheels/
A Python .whl
file is essentially a ZIP (.zip) archive with a specially crafted filename that tells installers what Python versions and platforms the wheel will support.
A wheel is a type of built
distribution. In this case, built means that the wheel comes in a ready-to-install format and allows you to skip the build stage required with source distributions.
Then you register account on PyPI and upload the package:
1 | ## install twine |
Tools used: twine: Twine is a utility for publishing Python packages on PyPI.
After uploading you can use pip install the paclage in your new virtual environment.