当前位置: 首页 > 面试题库 >

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

贺山
2023-03-14
问题内容

在Python中,命名空间包可让您在多个项目中传播Python代码。当您要将相关的库作为单独的下载发布时,这很有用。例如,目录Package-1Package-2PYTHONPATH

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

最终用户可以import namespace.module1import namespace.module2

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


问题答案:

TL; DR:

在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.path。如果foo.bar找到,foofoo.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.bar并且import package.baz将所有的工作。

pkg_resources.declare_namespace(__name__) 尚未更新为包括隐式名称空间包。



 类似资料:
  • 问题内容: 为了交互式测试我的python脚本,我想创建一个对象,类似于所返回的对象。显而易见的方式 可能会导致傻子错误导致Python repl退出(如上所述)。 那么, 用给定的属性集创建Python名称空间的最简单方法是什么? 例如,我可以即时创建一个(),但不能将其用作: 问题答案: 您可以创建一个简单的类: 在属性方面,它的工作方式与类完全相同: 或者,只需 导入类 ;可从模块中获得:

  • 我在一个多租户节点应用程序中工作,我知道要在Kubernetes中创建一个新的命名空间,可以运行一个kubectl命令,如下所示:

  • 问题内容: 假设有一个文件夹“ / home / user / temp/a40bd22344”。名称是完全随机的,并且在每次迭代中都会更改。我需要能够使用固定名称(例如“ project”)在Python中导入此文件夹。我知道我可以将此文件夹添加到sys.path中以启用导入查找,但是有没有一种方法可以将“a40bd22344”替换为“项目”? 也许 init .py有一些聪明的技巧? 添加:

  • 我在访问另一个命名空间中存在的服务时遇到问题。 我有两个名称空间(在同一个集群中)airflow-dev和dask-dev。 在dask-dev名称空间中,我部署了dask集群(dask调度器和工作器)。此外,还为dask-scheduler pod创建了一个服务(集群IP)。我可以使用“kubectl port-forward”命令从chrome访问dask-scheduler pod。 然而,

  • 问题内容: 如何在JavaScript中创建名称空间,以使我的对象和函数不会被其他同名对象和函数覆盖?我使用了以下内容: 有没有更优雅或更简洁的方法? 问题答案: 我喜欢这个:

  • 我想做的是能够从客户机创建一个房间,但好像它是一个对象。例如:我有一个名为“room”的类,这个类实现了3个事件,所以当你创建一个新的room时,你可以在每个事件中触发这些事件。这可能吗?以下是我的服务器代码: