Питон: доступ к атрибутам и методам одного класса в другой

предположим, у меня есть два класса 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. Итак, мы оказываемся в бесконечной рекурсии. Таким образом, этот подход отлично работает, когда вы не получаете доступ к чему-либо неизвестному обоим объектам.