クラスがありA
ます。__init__
のインスタンスのメソッド中A
。
B
クラスとの次の 2 つのインスタンスを作成しますC
。
b = B()
c = C()
すべてが設定されたら、 のメソッド内で のメソッドを呼び出す必要がありB
ますC
。
例:
引き金になった:
b.call_c()
行う:
def call_c(self):
parent.c.a_method_of_c()
この構造を実現するために何をする必要がありますか?
クラスがありA
ます。__init__
のインスタンスのメソッド中A
。
B
クラスとの次の 2 つのインスタンスを作成しますC
。
b = B()
c = C()
すべてが設定されたら、 のメソッド内で のメソッドを呼び出す必要がありB
ますC
。
例:
引き金になった:
b.call_c()
行う:
def call_c(self):
parent.c.a_method_of_c()
この構造を実現するために何をする必要がありますか?
他のオブジェクトについて知ることができるように、self
またはのいずれかc
を渡す必要があります。B()
B
のメソッド内で、からのメソッドを呼び出す必要がありますC
。
基本的に、メソッドがクラス メソッドでも静的メソッドでもない場合、メソッドを呼び出すことは常にc
、クラスの ( ) オブジェクトにアクセスできることを意味しますC
。
例を見てください:
#!python3
class B:
def __init__(self, value):
self.value = value
def __str__(self):
return 'class B object with the value ' + str(self.value)
class C:
def __init__(self, value):
self.value = value
def __str__(self):
return 'class C object with the value ' + str(self.value)
class A:
def __init__(self, value):
self.value = value
self.b = B(value * 2)
self.c = C(value * 3)
def __str__(self):
lst = ['class A object with the value ' + str(self.value),
' containing the ' + self.b.__str__(),
' containing also the ' + str(self.c),
]
return '\n'.join(lst)
a = A(1)
print(a)
print(a.b)
print(a.c)
クラスのオブジェクトのメソッドからクラスself.b.__str__()
のオブジェクトのメソッドを呼び出す例です。これは同じで、関数を介して間接的に呼び出されるだけです。B
A
str(self.c)
str()
以下が表示されます。
class A object with the value 1
containing the class B object with the value 2
containing also the class C object with the value 3
class B object with the value 2
class C object with the value 3
A オブジェクトを B と C の両方に親/コンテナー オブジェクトとして渡すと、次のようになります。
class A(object):
def __init__(self):
self.b = B(self)
self.c = C(self)
class B(object):
def __init__(self, parent):
self.parent = parent
def call_c(self):
self.parent.c.a_method_of_c()
class C(object):
def __init__(self, parent):
self.parent = parent
# whatever...
または、次のように C インスタンスを B の初期化子に渡すこともできます。
class A(object):
def __init__(self):
self.c = C()
self.b = B(self.c)
class B(object):
def __init__(self, c):
self.cobj = c
def call_c(self):
self.cobj.a_method_of_c()
class C(object):
# whatever...
b
B と C の A への依存関係と、A の実装とc
属性の必要性を排除するので、私は 2 番目のアプローチの方が好きです。
B と C が相互にメソッドを呼び出す必要がある場合でも、A を使用してこれらの関連付けを行うことができますが、B と C は A を認識しないままにしておきます。
class A(object):
def __init__(self):
self.b = B()
self.c = C()
self.b.cobj = self.c
self.c.bobj = self.b
class B(object):
def __init__(self, c):
self.cobj = None
def call_c(self):
if self.cobj is not None:
self.cobj.a_method_of_c()
else:
raise Exception("B instance not fully initialized")
class C(object):
# similar to B
一般に、あなたの目標は、これらの依存関係を回避するか、少なくとも最小限に抑えようとすることです。親には子について知ってもらいますが、子には親のことを知らないようにしてください。または、コンテナーは含まれているオブジェクトを認識していますが、含まれているオブジェクトはそのコンテナーを認識していません。循環参照 (親またはコンテナー オブジェクトへの逆参照) を追加すると、あらゆる種類の驚くべき方法で事態が悪化する可能性があります。リンクの 1 つがクリアされても、リフレクティング リンクがクリアされない場合、関係が壊れる可能性があります。または、循環リレーションのガベージ コレクションは扱いにくくなる可能性があります (Python 自体で処理されますが、これらのオブジェクトとリレーションがフレームワークで永続化または複製される場合は処理されない可能性があります)。