Python: accessing attributes and methods of one cl

2019-06-17 02:01发布

Let's say I have two classes A and B:

Class A:
   # A's attributes and methods here

Class B:
  # B's attributes and methods here

Now I can assess A's properties in object of B class as follows:

a_obj = A()
b_obj = B(a_obj)

What I need is a two way access. How do I access A's properties in B and B's properties in A ?

标签: python oop
3条回答
仙女界的扛把子
2楼-- · 2019-06-17 02:11

You need to create pointers either way:

class A(object):
    parent = None


class B(object):
    def __init__(self, child):
        self.child = child
        child.parent = self

Now A can refer to self.parent (provided it is not None), and B can refer to self.child. If you try to make an instance of A the child of more than one B, the last 'parent' wins.

查看更多
贪生不怕死
3楼-- · 2019-06-17 02:13

Why not just plan your objects in a way where this can be taken care of with inheritance.

class A(object):
    # stuff

class B(A):
    # has A methods/properties

class C(B):
    # has A and B methods/properties

In this case by planing ahead, you could just use C for a generalist object, and A with B as more specialised/bare parents.

查看更多
神经病院院长
4楼-- · 2019-06-17 02:23

This method will be very useful, as you can use objects of both the classes interchangeably. There is a serious problem with this, I ll explain that at the end.

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 + "`")

Explanation:

As per this page, __getattr__ and __setattr__ will be invoked on python objects only when the requested attribute is not found in the particular object's space. So in the constructor we are establishing relationship between both the classes. And then whenever __getattr__ or __setattr__ is called, we refer the other object using getattr method. (getattr, setattr) We use __dict__ to assign values in the constructor, so that we ll not call __setattr__ or __getattr__.

Sample Runs:

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

Now, the serious problem:

If we try to access an attribute which is not there in both these objects, we ll end up in infinite recursion. Lets say I want to access 'C' from 'a'. Since C is not in a, it will call __getattr__ and it will refer b object. As b object doesnt have C, it will call __getattr__ which will refer object a. So we end up in an infinite recursion. So this approach works fine, when you you don't access anything unknown to both the objects.

查看更多
登录 后发表回答