背景の問題
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]()