简体   繁体   English

Python:访问另一个类的属性和方法

[英]Python: accessing attributes and methods of one class in another

Let's say I have two classes A and B: 假设我有两个A和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: 现在我可以在B类对象中评估A的属性,如下所示:

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 ? 如何访问A中B和B属性中的A属性?

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 . 现在A可以引用self.parent (假设它不是None ), B可以引用self.child If you try to make an instance of A the child of more than one B , the last 'parent' wins. 如果您尝试将A的实例设为多于一个B的子项,则最后一个'父'获胜。

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. 在这种情况下,通过提前计划,你可以只使用C作为通用对象,而A B作为更专业/裸露的父对象。

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. 根据此页面 ,仅当在特定对象的空间中找不到请求的属性时,才会在python对象上调用__getattr____setattr__ 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__ ,我们使用getattr方法引用另一个对象。 ( getattr , setattr ) We use __dict__ to assign values in the constructor, so that we ll not call __setattr__ or __getattr__ . getattrsetattr )我们使用__dict__在构造函数中赋值,这样我们就不会调用__setattr____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'. 假设我想从'a'访问'C'。 Since C is not in a, it will call __getattr__ and it will refer b object. 由于C不在a中,它将调用__getattr__并且它将引用b对象。 As b object doesnt have C, it will call __getattr__ which will refer object a. 由于b对象没有C,它将调用__getattr__ ,它将引用对象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. 因此,当您不访问对象未知的任何内容时,此方法可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM