导入子包访问父包命名空间中的对象?

问题描述 投票:0回答:1

这个非常棒 描述命名空间如何受导入影响。然而我发现, 以下观点仅部分正确:

  • import packagename.nestedmodule
    packagename = sys.modules['packagename']
    (无论您有多少额外级别) 添加)

我从 Spyder 控制台执行了以下操作:

import pyspark.sql as sql, sys

这里,

pyspark
是一个包,而
sql
是一个子包(两者都是 这也是模块)。

上面没有在命名空间中创建了一个pyspark

对象
重复。然而,它确实创建了条目 
sys.modules["pyspark"]
除了
sys.modules["pyspark.sql"]

有什么方法可以访问父包的命名空间, 对应于sys.modules["pyspark"]

,无需导入
单独吗?
虽然我不是 100% 确定,但该条目 sys.modules["pyspark"]
向我建议,代码中
pyspark/__init__.py
已经被执行了。如果是这样,那么对象
已经在某个范围内漂浮在某个地方,由
蟒蛇。

这个问题与我的

过去不同 问题,但是 这里的答案可以为旧问题提供答案。

python-import
1个回答
0
投票
要访问模块及其对象,您需要将它们导入您的命名空间或使用

sys.modules

它是一个将模块名称映射到模块的字典。根据您想要实现的目标(详细信息会有所帮助),也可以通过 import 语句动态完成或直接通过“import 语句的实现”来完成,即 importlib。请参阅 (importlib.import_module)[https://docs.python.org/3/library/importlib.html#importlib.import_module],并注意模块可以是命名空间中的对象。所以通过这个,你可以做例如

# Case ` catalog = importlib.import_module('catalog','pyspark.sql'). Database = catalog.Database
相当于

# Case 2 from pyspark.sql import catalog Database = catalog.Database
但不

# Case 3 from pyspark.sql.catalog import Database
这 3 种情况的区别在于你的命名空间中的 

locals()

。当 
pyspark.__init__.py
pyspark.sql.__init__.py
 都被执行时,它们的属性不会被导入,只导入 import 语句指定的属性。情况 #1 和情况 #2 是等效的,也许除了您需要先导入 importlib (讽刺)这一事实。

事实上,使用

sys.modules

 是访问已加载但不在命名空间中的模块的方法(即使不导入它们)。
    

© www.soinside.com 2019 - 2024. All rights reserved.