Ta metoda będzie bardzo przydatna, ponieważ można używać obiektów obu klas zamiennie. Jest z tym poważny problem, wyjaśnię to na końcu.
class A:
def MethodA(self):
return "Inside MethodA"
def __init__ (self, Friend=None):
self.__dict__['a'] = "I am a"
self.__dict__['Friend'] = Friend
if Friend is not None: self.__dict__['Friend'].__dict__['Friend'] = self
def __getattr__(self, name):
if self.Friend is not None: return getattr(self.Friend, name)
raise AttributeError ("Unknown Attribute `" + name + "`")
def __setattr__(self, name, value):
if self.Friend is not None: setattr(self.Friend, name, value)
raise AttributeError ("Unknown Attribute `" + name + "`")
class B:
def MethodB(self):
return "Inside MethodB"
def __init__ (self, Friend=None):
self.__dict__['b'] = "I am b"
self.__dict__['Friend'] = Friend
if Friend is not None: self.__dict__['Friend'].__dict__['Friend'] = self
def __getattr__(self, name):
if self.Friend is not None: return getattr(self.Friend, name)
raise AttributeError ("Unknown Attribute `" + name + "`")
def __setattr__(self, name, value):
if self.Friend is not None: setattr(self.Friend, name, value)
raise AttributeError ("Unknown Attribute `" + name + "`")
Objaśnienie:
Zgodnie this page, __getattr__
i __setattr__
zostanie wywołana na obiekty Pythona tylko wtedy, gdy wnioskowana atrybut nie zostanie znaleziony w przestrzeni danego obiektu za. Tak więc w konstruktorze nawiązujemy relację między obiema klasami. Następnie, gdy wywoływane jest __getattr__
lub __setattr__
, odsyłamy drugi obiekt za pomocą metody getattr
. (getattr, setattr) Używamy __dict__
, aby przypisać wartości w konstruktorze, abyśmy nie zadzwonili pod numer __setattr__
lub __getattr__
.
Przykładowe zjazdowe:
b = B()
# print b.a # Throws AttributeError, as A and B are not related yet
a = A(b)
print a.a
print a.b
print b.a # Works fine here, as 'a' is not found b, returns A's a
print b.b
print a.MethodA()
print a.MethodB()
print b.MethodA()
print b.MethodB()
I am a
I am b
I am a
I am b
Inside MethodA
Inside MethodB
Inside MethodA
Inside MethodB
Teraz poważny problem:
Jeśli spróbujemy uzyskać dostęp do atrybutu, który nie jest tam w obu tych obiektów, ll skończyć się w nieskończony rekurencja. Powiedzmy, że chcę uzyskać dostęp do "C" z "a". Ponieważ C nie jest w a, będzie wywoływać __getattr__
i będzie odnosić się do obiektu b. Ponieważ obiekt b nie ma C, wywoła on __getattr__
, który będzie odnosił się do obiektu a. Więc kończymy w nieskończonej rekursji. Tak więc to podejście działa dobrze, gdy nie uzyskujesz dostępu do niczego nieznanego obu obiektom.
Czy masz na myśli, że chcesz uzyskać dostęp do członków a_obj w b_obj? A może chcesz, aby klasy miały właściwości o tych samych nazwach? – Ishpeck
Chcę uzyskać dostęp do właściwości każdego obiektu z drugiego (wzajemny dostęp), a odpowiedź Martjina pozwala mi to zrobić :) – oat