背景问题
python 程序导入一些模块,每个模块创建各种类。它还导入了一个带有子模块的包,这些子模块需要能够看到 Python 程序顶层可用的所有类。包子模块如何查看其导入器可用的所有类?
这是我当前的解决方案,它有效,但它需要顶级程序从子模块创建一个实例并通过globals()
实例方法传入字典(见下文)。至少在导入包的子模块后只需执行一次。
什么是不需要顶级程序通过其的更好的方法globals()
?如果可能的话,我希望这对顶级程序透明地自动发生。
带注释的输出
$ python top_t.py
Hi, I'm an instance of ModM!
# Expected, but not desired.
ModM in SubModS:0's globals = No
Adding globals from higher level to level of SubModS.
# Yeah!
ModM in SubModS:0's globals = Yes
# Persistent
ModM in SubModS:1's globals = Yes
# Sufficient to create a new instance from submodule.
Hi, I'm an instance of ModM!
代码
top_t.py
from mod_m import ModM
from package_p import SubModS
m0 = ModM()
s0 = SubModS(0)
s0.see_class('ModM')
s0.broaden_view(globals())
s0.see_class('ModM')
s1 = SubModS(1)
s1.see_class('ModM')
m1 = s0.create_inst('ModM')
mod_m.py
class ModM(object):
def __init__(self):
print "Hi, I'm an instance of ModM!"
package_p/__init__.py
__all__ = ['SubModS']
from .submod_s import SubModS
package_p/submod_s.py
class SubModS(object):
def __init__(self, i):
self.i = i
def see_class(self, cls):
print "{} in {}:{}'s globals = {}".format(cls, self.__class__.__name__, self.i, 'Yes' if cls in globals() else 'No')
def broaden_view(self, higher_globals):
print 'Adding globals from higher level to level of {}.'.format(self.__class__.__name__)
local_globals = globals()
for nm, ob in higher_globals.iteritems():
if nm not in local_globals:
local_globals[nm] = ob
def create_inst(self, cls):
return globals()[cls]()