首页 > 编程笔记 > Python笔记 > Python打包和发布
Python命名空间包
提到命名空间,其实包含 2 层含义,一种是语言上下文的命名空间,其实在编写 Python 程序时,无时无刻都在使用命名空间,比如模块使用的全局命名空间、函数或方法调用的本地命名空间等;另一种命名空间可以在包的层面提供,称为命名空间包。
简单的理解,命名空间包是对相关的包或模块进行分组的一种方法,通常是一个被忽略的功能,它对于在较大的项目中构建打包生态系统非常有用。
如果你的应用组件的开发、打包和版本化都是独立的,但仍然希望从同一个命名空间访问它们,那么命名空间包特别有用,它有利于明确每个包所属的组织或项目。
例如,假设有一个 Acme 公司,该公司中使用共同的 acme 命名空间,同时创建通用的 acme 命名空间包作为该组织的其他包的容器。如果 Acme 公司中的某人想要向这个命名空间贡献一个与 SQL 相关的库,那么他需要在 acme 中注册自己新的 acme.sql 包,整个文件结构如下所示:
通过利用命名空间包,我们可以单独保存每个子包的源代码树,如下所示:
简单来说,对于每一个包含 Python 包或模块(也包括命名空间包)的目录来说,如果其不包含 __init__().py 文件,那么它就被看做是命名空间包。
例如,前面所说的 acme 在 Python 3.3 以及更高版本中,就是一个命名空间包。使用安装工具的最小 setup.py 脚本文件如下所示:
最简单的方法就是为每个组件创建一个文件结构,类似于没有命名空间包的普通包布局,并将所有事情都留给 setuptools。
因此,acme.sql 和 acme.templating 的布局示例可能如下所示:
如果我们提供 acme 作为 setuptools.setup() 函数 namespace_package 关键字参数的值,那么将会创建如下的 acme 命名空间包:
无论如何,正如官方文档所说,你自己负责在 __init__.py 文件中声明命名空间,并且未来可能会删除 setuptools 的这个隐式行为。为了保证安全,也为了未来依然可用(future-proof),需要将下面这行代码添加到 acme/__init__.py 文件中:
简单的理解,命名空间包是对相关的包或模块进行分组的一种方法,通常是一个被忽略的功能,它对于在较大的项目中构建打包生态系统非常有用。
如果你的应用组件的开发、打包和版本化都是独立的,但仍然希望从同一个命名空间访问它们,那么命名空间包特别有用,它有利于明确每个包所属的组织或项目。
例如,假设有一个 Acme 公司,该公司中使用共同的 acme 命名空间,同时创建通用的 acme 命名空间包作为该组织的其他包的容器。如果 Acme 公司中的某人想要向这个命名空间贡献一个与 SQL 相关的库,那么他需要在 acme 中注册自己新的 acme.sql 包,整个文件结构如下所示:
$tree acme/ acme/ ├───acme │ ├───__init__.py │ └───sql │ └──__init__.py └───setup.py 2 directories, 3 files在此基础上,如果想添加一个新的子包,例如添加 templating,则需要将其包含在 acme 的源代码树中,如下所示:
$tree acme/ acme/ ├───acme │ ├───__init__.py │ ├───sql │ │ └──__init__.py │ └───templating │ └──__init__.py └───setup.py 3 directories, 4 files仔细观察就会发现,采用这种方式几乎不可能单独开发 acme.sql 和 acme.templating。且 setup.py 脚本还必须指定每个子包的所有依赖,所以不可能(至少非常困难)选择性地安装 acme 中的部分组件。此外,如果某些子包的需求文件有冲突,是一个无法解决的问题。
通过利用命名空间包,我们可以单独保存每个子包的源代码树,如下所示:
$tree acme.sql/ acme.sql/ ├───acme │ └───sql │ └──__init__.py └───setup.py 2 directories, 2 files $tree acme.templating/ acme.templating/ ├───acme │ └───templating │ └──__init__.py └───setup.py 2 directories, 2 files由此,就可以在 PyPI 或者使用的任何包索引中单独注册它们,用户还可以从 acme 命名空间中选择想要安装的子包,而无需安装通用的 acme 包,执行代码如下:
$pip install acme.sql acme.templating
注意,独立的源代码树不足以在 Python 中创建命名空间包,如果不想让包之间相互覆盖,就需要做一些额外的工作,此外,正确的处理方式也会随着 Python 版本的不同而有所不同。隐式命名空间包
如果你只使用 Python 3.x,也只面向 Python 3.x 的用户,则可以使用 PEP 420 引入的定义命令空间的新方法,即隐式命名空间包。它是标准路径的一部分,并从 Python 3.3 版本开始成为语言官方内容的一部分。简单来说,对于每一个包含 Python 包或模块(也包括命名空间包)的目录来说,如果其不包含 __init__().py 文件,那么它就被看做是命名空间包。
例如,前面所说的 acme 在 Python 3.3 以及更高版本中,就是一个命名空间包。使用安装工具的最小 setup.py 脚本文件如下所示:
from setuptools import setup setup( name = 'acme.templating', packages = ['acme.templating'], )但是,直到发表本节时,setuptools.find_packages() 还不支持 PEP 420,但这在未来很可能会改变。此外,要想实现命名空间包的简单继承,显示地定义包列表是值得的。
以前Python版本中的命名空间包
Python 3.3 之前的版本中,虽无法使用 PEP 420 布局中的命名空间包,但仍可以使用它。旧版 Python 中,有几种方法可以将包定义成命名空间。最简单的方法就是为每个组件创建一个文件结构,类似于没有命名空间包的普通包布局,并将所有事情都留给 setuptools。
因此,acme.sql 和 acme.templating 的布局示例可能如下所示:
$tree acme.sql/ acme.sql/ ├───acme │ ├──__init__.py │ └───sql │ └──__init__.py └───setup.py 2 directories, 3 files $tree acme.templating/ acme.templating/ ├───acme │ ├──__init__.py │ └───templating │ └──__init__.py └───setup.py 2 directories, 3 files注意,acme.sql 和 acme.templating 都有一个额外的源代码文件 acme/__init__.py,这个文件必须是空的。
如果我们提供 acme 作为 setuptools.setup() 函数 namespace_package 关键字参数的值,那么将会创建如下的 acme 命名空间包:
from setuptools import setup setup( name = 'acme.templating', packages = ['acme.templating'], namespace_package = ['acme'], )当然,最简单的方法不一定是最好的,为了注册一个新的命名空间,setuptools 将会在 __init__.py 文件中调用 pkg_resources.declare_namespace() 函数,即便 __init__.py 文件是空的也会调用。
无论如何,正如官方文档所说,你自己负责在 __init__.py 文件中声明命名空间,并且未来可能会删除 setuptools 的这个隐式行为。为了保证安全,也为了未来依然可用(future-proof),需要将下面这行代码添加到 acme/__init__.py 文件中:
__import__('pkg_resources').declare_namespace(__name__)
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算