如何在 Python 中创建命名空间包?

2025-01-22 08:45:00
admin
原创
99
摘要:问题描述:在 Python 中,命名空间包允许您将 Python 代码分散到多个项目中。当您想将相关库作为单独的下载发布时,这很有用。例如,使用中的目录Package-1和,Package-2`PYTHONPATH`Package-1/namespace/__init__.py Package-1/names...

问题描述:

在 Python 中,命名空间包允许您将 Python 代码分散到多个项目中。当您想将相关库作为单独的下载发布时,这很有用。例如,使用中的目录Package-1和,Package-2`PYTHONPATH`

Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py

最终用户可以import namespace.module1并且import namespace.module2

定义命名空间包的最佳方法是什么,以便多个 Python 产品可以在该命名空间中定义模块?


解决方案 1:

总结:

在 Python 3.3 上,您无需执行任何操作,只需不将任何内容放入__init__.py命名空间包目录中,它就会正常工作。在 3.3 之前的版本中,请选择pkgutil.extend_path()解决方案pkg_resources.declare_namespace(),因为它面向未来并且已经与隐式命名空间包兼容。


Python 3.3 引入了隐式命名空间包,参见PEP 420。

这意味着现在可以创建三种类型的对象import foo

  • foo.py由文件表示的模块

  • 常规包,由foo包含__init__.py文件的目录表示

  • 命名空间包,由一个或多个foo不带任何__init__.py文件的目录表示

包也是模块,但是这里我说的“模块”是指“非包模块”。

首先,它会扫描sys.path模块或常规包。如果成功,它会停止搜索并创建和初始化模块或包。如果未找到模块或常规包,但找到至少一个目录,它会创建并初始化命名空间包。

模块和常规包已__file__设置为.py创建它们的文件。常规包和命名空间包已__path__设置为创建它们的目录。

当你执行 时import foo.bar,上述搜索首先针对 进行,然后如果找到了包,则使用作为搜索路径而不是进行foo搜索。如果找到了 ,则创建并初始化 和 。bar`foo.__path__sys.pathfoo.barfoofoo.bar`

那么常规包和命名空间包如何混合呢?通常它们不会混合,但是旧的pkgutil显式命名空间包方法已扩展为包括隐式命名空间包。

如果您现有的常规包有如下内容__init__.py

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

... 传统行为是将搜索路径上的任何其他常规__path__包添加到其。 但在 Python 3.3 中,它还添加了命名空间包。

因此你可以拥有以下目录结构:

├── path1
│   └── package
│       ├── __init__.py
│       └── foo.py
├── path2
│   └── package
│       └── bar.py
└── path3
    └── package
        ├── __init__.py
        └── baz.py

...只要两行__init__.pyextend_path(和path1path2path3在你的sys.pathimport package.fooimport package.barimport package.baz都可以。

pkg_resources.declare_namespace(__name__)尚未更新以包含隐式命名空间包。

解决方案 2:

有一个名为pkgutil的标准模块,您可以使用它将模块“附加”到给定的命名空间。

使用您提供的目录结构:

Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py

您应该将这两行放在Package-1/namespace/__init__.pyPackage-2/namespace/__init__.py(*)中:

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

(* 因为 - 除非你声明它们之间的依赖关系 - 你不知道哪一个会首先被识别 -有关更多信息,请参阅PEP 420 )

正如文档所述:

这会将以该包命名的__path__目录的所有子目录添加到包中sys.path

从现在开始,您应该能够独立分发这两个包。

解决方案 3:

本节内容应非常清晰易懂。

简而言之,将命名空间代码放入__init__.py,更新setup.py以声明命名空间,然后就可以自由使用了。

解决方案 4:

这是一个老问题,但最近有人在我的博客上评论说我关于命名空间包的帖子仍然具有相关性,所以我想在这里链接到它,因为它提供了一个如何实现它的实用示例:

https://web.archive.org/web/20150425043954/http://cdent.tumblr.com/post/216241761/python-namespace-packages-for-tiddlyweb

这篇文章的链接可以让你了解事情的主要内容:

http://www.siafoo.net/article/77#multiple-distributions-one-virtual-package

这个__import__("pkg_resources").declare_namespace(__name__)技巧基本上推动了TiddlyWeb中插件的管理,到目前为止似乎很有效。

解决方案 5:

您的 Python 命名空间概念完全颠倒了,在 Python 中不可能将包放入模块中。包包含模块,而不是相反。

Python 包只是一个包含__init__.py文件的文件夹。模块是包中(或直接在 上PYTHONPATH)具有.py扩展名的任何其他文件。因此,在您的示例中,您有两个包,但没有定义模块。如果您认为包是文件系统文件夹,而模块是文件,那么您就会明白为什么包包含模块,而不是相反。

因此,在您的示例中,假设 Package-1 和 Package-2 是您放在 Python 路径上的文件系统上的文件夹,您可以获得以下内容:

Package-1/
  namespace/
  __init__.py
  module1.py
Package-2/
  namespace/
  __init__.py
  module2.py

您现在有一个namespace包含两个模块module1和的包module2。除非您有充分的理由,否则您应该将模块放在文件夹中,并且只在 python 路径上放置该模块,如下所示:

Package-1/
  namespace/
  __init__.py
  module1.py
  module2.py
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2974  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1836  
  PLM(产品生命周期管理)系统在企业的产品研发、生产与管理过程中扮演着至关重要的角色。然而,在实际运行中,资源冲突是经常会遇到的难题。资源冲突可能导致项目进度延迟、成本增加以及产品质量下降等一系列问题,严重影响企业的效益与竞争力。因此,如何有效应对PLM系统中的资源冲突,成为众多企业关注的焦点。接下来,我们将详细探讨5...
plm项目管理系统   47  
  敏捷项目管理与产品生命周期管理(PLM)的融合,正成为企业在复杂多变的市场环境中提升研发效率、增强竞争力的关键举措。随着技术的飞速发展和市场需求的快速更迭,传统的研发流程面临着诸多挑战,而将敏捷项目管理理念融入PLM,有望在2025年实现研发流程的深度优化,为企业创造更大的价值。理解敏捷项目管理与PLM的核心概念敏捷项...
plm项目   47  
  模块化设计在现代产品开发中扮演着至关重要的角色,它能够提升产品开发效率、降低成本、增强产品的可维护性与可扩展性。而产品生命周期管理(PLM)系统作为整合产品全生命周期信息的关键平台,对模块化设计有着强大的支持能力。随着技术的不断发展,到 2025 年,PLM 系统在支持模块化设计方面将有一系列令人瞩目的技术实践。数字化...
plm软件   48  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用