Питон: доступ к атрибутам и методам одного класса в другой
предположим, у меня есть два класса A и B:
Class A:
# A's attributes and methods here
Class B:
# B's attributes and methods here
теперь я могу оценить свойства A в объекте класса B следующим образом:
a_obj = A()
b_obj = B(a_obj)
мне нужен двусторонний доступ. Как получить доступ к свойствам A в свойствах B и B в A ?
3 ответов
вам нужно создать указатели в любом случае:
class A(object):
parent = None
class B(object):
def __init__(self, child):
self.child = child
child.parent = self
теперь A
может относиться к self.parent
(при условии, что это не None
), и B
может относиться к self.child
. Если вы попытаетесь сделать экземпляр A
ребенок более чем одного B
последняя "родитель" выигрывает.
Почему бы просто не планировать свои объекты таким образом, чтобы об этом можно было позаботиться с наследованием.
class A(object):
# stuff
class B(A):
# has A methods/properties
class C(B):
# has A and B methods/properties
в этом случае, планируя вперед, вы можете просто использовать C
для объекта обобщения и A
С B
как более специализированные/голые родители.
этот метод будет очень полезен, как вы можете использовать объекты и классы взаимозаменяемы. Есть серьезная проблема с этим, я объясню это в конце.
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 + "`")
объяснение:
по состоянию на на этой странице, __getattr__
и __setattr__
будет вызываться на объектах python только тогда, когда запрошенный атрибут не найден в пространстве конкретного объекта. Таким образом, в конструкторе мы устанавливаем связь между обоими занятия. А потом, когда ... --2--> или __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. Итак, мы оказываемся в бесконечной рекурсии. Таким образом, этот подход отлично работает, когда вы не получаете доступ к чему-либо неизвестному обоим объектам.