Этот метод будет очень полезен, так как вы можете использовать объекты обоих классов взаимозаменяемо. В этом есть серьезная проблема, я объясню это в конце.
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 + "`")
Объяснение:
Согласно this page, __getattr__
и __setattr__
будут вызываться на объектах питона только тогда, когда запрашиваемый атрибут не найден в пространстве конкретного объекта. Поэтому в конструкторе мы устанавливаем связь между обоими классами. И тогда, когда вызывается __getattr__
или __setattr__
, мы ссылаемся на другой объект, используя метод getattr
. (getattr, setattr) Мы используем __dict__
для назначения значений в конструкторе, чтобы мы не вызывали __setattr__
или __getattr__
.
Примеры Запускаются:
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
Теперь серьезная проблема:
Если попытаться получить доступ к атрибуту, который не является там в обеих этих объектах, мы будем в конечном итоге в бесконечном рекурсии. Допустим, я хочу получить доступ к 'C' из 'a'. Поскольку C не находится в a, он будет называть __getattr__
, и он будет ссылаться на объект b. Поскольку объект b не имеет C, он вызывает __getattr__
, который будет ссылаться на объект a. Таким образом, мы оказываемся в бесконечной рекурсии. Таким образом, этот подход работает отлично, когда вы не получаете доступ к чему-либо неизвестному для обоих объектов.
Вы хотите сказать, что хотите получить доступ к членам a_obj в b_obj? Или вы просто хотите, чтобы классы имели свойства с одинаковыми именами? – Ishpeck
Я хочу получить доступ к свойствам каждого объекта из другого (взаимный доступ), и ответ Марджина позволяет мне это сделать :) – oat