私が使用するいくつかのPythonコードを作成した外部クラスをそのから内部クラス別の良いアイデアをもとに、答えこの質問について。短くてシンプルでわかりやすいと思います。
class higher_level__unknown_irrelevant_name__class:
def __init__(self, ...args...):
...other code...
# Important lines to access sub-classes.
subclasses = self._subclass_container()
self.some_subclass = subclasses["some_subclass"]
del subclasses # Free up variable for other use.
def sub_function(self, ...args...):
...other code...
def _subclass_container(self):
_parent_class = self # Create access to parent class.
class some_subclass:
def __init__(self):
self._parent_class = _parent_class # Easy access from self.
# Optional line, clears variable space, but SHOULD NOT BE USED
# IF THERE ARE MULTIPLE SUBCLASSES as would stop their parent access.
# del _parent_class
class subclass_2:
def __init__(self):
self._parent_class = _parent_class
# Return reference(s) to the subclass(es).
return {"some_subclass": some_subclass, "subclass_2": subclass_2}
メインコードの「プロダクションレディ」(コメントなどなし)。山かっこ内のすべての値(例:)を<x>
目的の値に置き換えてください。
class <higher_level_class>:
def __init__(self):
subclasses = self._subclass_container()
self.<sub_class> = subclasses[<sub_class, type string>]
del subclasses
def _subclass_container(self):
_parent_class = self
class <sub_class>:
def __init__(self):
self._parent_class = _parent_class
return {<sub_class, type string>: <sub_class>}
このメソッドがどのように機能するかについての説明(基本的な手順):
(関数内で実行されているコードからの)上位レベルのクラスへの参照で_subclass_container
あるvariableにアクセスするためのラッパーとして機能するという名前の関数を作成しますself
。
のサブクラスがアクセスできるこの関数_parent_class
の変数への参照であるという名前の変数を作成します(サブクラス内の他の変数との名前の競合を回避します)。self
_subclass_container
self
_subclass_container
関数を呼び出すコードが内部のサブクラスにアクセスできるように、サブクラス/サブクラスを辞書/リストとして返します。
__init__
上位レベルのクラス内の関数(または他の必要な場所)で、関数から返されたサブクラスを_subclass_container
変数に受け取りますsubclasses
。
subclasses
変数に格納されているサブクラスを上位レベルのクラスの属性に割り当てます。
シナリオを簡単にするためのいくつかのヒント:
サブクラスを上位クラスに割り当てるコードをコピーしやすくし、 機能が変更された上位クラスから派生したクラスで使用できるようにします__init__
。
メインコードの12行目の前に挿入します。
def _subclass_init(self):
次に、この関数に(メインコードの)5〜6行目を挿入し、4〜7行目を次のコードに置き換えます。
self._subclass_init(self)
サブクラスの数が多いか不明な場合に、サブクラスをより高いレベルのクラスに割り当てることができるようにします。
6行目を次のコードに置き換えます。
for subclass_name in list(subclasses.keys()):
setattr(self, subclass_name, subclasses[subclass_name])
このソリューションが役立つ場合、およびより高いレベルのクラス名を取得できない場合のシナリオ例:
「a」という名前のクラス(class a:
)が作成されます。アクセスする必要があるサブクラス(親)があります。1つのサブクラスは「x1」と呼ばれます。このサブクラスでは、コードa.run_func()
が実行されます。
次に、クラス「a」から派生した「b」という名前の別のクラスが作成されclass b(a):
ます()。その後、いくつかのコードが実行されますb.x1()
(派生サブクラスbのサブ関数 "x1"を呼び出します)。この関数はa.run_func()
、クラス「a」で定義された関数が参照するように設定されているため、親「b」の関数「run_func 」ではなく、クラス「a」の関数「run_func」を呼び出して実行します。それがその親であったので、クラス "a"の関数に。
これは問題を引き起こし(関数a.run_func
が削除された場合など)、クラスのコードを書き直さない唯一の解決策a.x1
は、x1
クラス "a"から派生したすべてのクラスの更新されたコードでサブクラスを再定義することです。それ。