在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产品可以在该名称空间中定义模块?
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
找到,foo
并foo.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__.py
有extend_path
行(和path1
,path2
并path3
在你的sys.path
)import package.foo
,import 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时,你可以在每个事件中触发这些事件。这可能吗?以下是我的服务器代码: