gpt4 book ai didi

python - 将子目录添加到 python 命名空间

转载 作者:太空宇宙 更新时间:2023-11-03 11:33:30 25 4
gpt4 key购买 nike

我希望能够导入一个实际上位于另一个模块的子目录中的 python 模块。

我正在开发一个带有插件的框架。因为我期望有几千个(目前已经超过 250 个)并且我不想要一个包含超过 1000 个文件的大目录,所以我将它们排序在这样的目录中,它们按名称的第一个字母分组:

framework\
__init__.py
framework.py
tools.py
plugins\
__init__.py
a\
__init__.py
atlas.py
...
b\
__init__.py
binary.py
...
c\
__init__.py
cmake.py
...

因为我不想给其他插件的开发者带来负担,或者不需要像我一样多的人,所以我想把每个插件都放在“framework.plugins”命名空间中。这样,添加一堆私有(private)插件的人可以通过将它们添加到文件夹 framework.plugins 中来实现,并提供一个 __init__.py 文件,其中包含:

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

但是,目前此设置迫使他们也使用 a-z 子目录。有时一个插件会扩展另一个插件,所以现在我有一个

from framework.plugins.a import atlas

我想拥有

from framework.pugins import atlas

有没有什么方法可以声明一个 namespace ,其中全 namespace 名称实际上不映射到文件夹结构?

我知道 pkg_resources 包,但这只能通过 setuptools 获得,我不想有额外的依赖。

import pkg_resources
pkg_resources.declare_namespace(__name__)

该解决方案应适用于 python 2.4-2.7.3

更新:结合提供的答案,我试图从插件中获取 __init__.py 中导入的所有插件的列表。但是,由于依赖关系,这失败了。由于 'c' 文件夹中的插件试图导入以 't' 开头的插件,而这个插件尚未添加。

plugins = [ x[0].find_module(x[1]).load_module(x[1]) for x in pkgutil.walk_packages([ os.path.join(framework.plugins.__path__[0], chr(y)) for y in xrange(ord('a'), ord('z') + 1) ],'framework.plugins.' ) ]

我不确定我是否在正确的轨道上,或者只是让事情过于复杂,最好编写我自己的 PEP302 导入器。但是,我似乎找不到任何像样的例子来说明这些应该如何工作。

更新:我尝试按照建议将 __getattr__ 函数包装在我的 __init__.py 中,但这似乎无济于事。

import pkgutil
import os
import sys
plugins = [x[1] for x in pkgutil.walk_packages([ os.path.join(__path__[0], chr(y)) for y in xrange(ord('a'), ord('z') + 1) ] )]
import types
class MyWrapper(types.ModuleType):
def __init__(self, wrapped):
self.wrapped = wrapped

def __getattr__(self, name):
if name in plugins:
askedattr = name[0] + '.' + name
else:
askedattr = name
attr = getattr(self.wrapped, askedattr)
return attr


sys.modules[__name__] = MyWrapper(sys.modules[__name__])

最佳答案

一个简单的解决方案是在 plugins.__init__ 中导入您的 ab... 模块,例如:

from a import atlas
from b import binary
...

关于python - 将子目录添加到 python 命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12040689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com