Python 从另一个对象B本身访问对象A的属性A的属性

Python 从另一个对象B本身访问对象A的属性A的属性,python,oop,Python,Oop,我正在研究一个物理问题,涉及一组(物理)对象(我们称之为B)它们与另一个(物理)对象(我们称之为a)的关系。每个B都有各自的属性,这些属性的计算可能取决于A的属性。A是唯一的,并且与A断开,B没有目的或意义。 有没有办法从B的类定义中访问a的属性,如果要从a的实例实例化对象B,那么a的属性将位于同一“级别”上?差不多 class A(object): def __init__(self, foo, bar, b1, b2): self.foo = foo

我正在研究一个物理问题,涉及一组(物理)对象(我们称之为B)它们与另一个(物理)对象(我们称之为a)的关系。每个B都有各自的属性,这些属性的计算可能取决于A的属性。A是唯一的,并且与A断开,B没有目的或意义。 有没有办法从B的类定义中访问a的属性,如果要从a的实例实例化对象B,那么a的属性将位于同一“级别”上?差不多

class A(object):
    def __init__(self, foo, bar, b1, b2):
        self.foo = foo
        self.bar = bar
        self.list_bs = [b1, b2]  # instances of B

class B(object):
    def computation(self):
        # something involving foo or bar, magically accessed
我觉得我有四个选择(…是为了简洁,而不是Python省略号):

  • 将A的实例传递给B的构造函数
    class A(object):
        def add(self, b):
            self.list_bs.append(b)
    
    class B(object):
        __init__(self, a, ...):
            self.a = a
            ...
            ...
    
        def compute1(self):
            # something involving self.a.foo
    
        def compute2(self):
            # something involving self.a.bar
    
    a = A()
    a.add(B(a, ...))
    a.add(B(a, ...))
    
    class A(object):
        def add(self, b):
            self.list_bs.append(b)
    
    class B(object):
        def __init__(self, a1, a2, ...):
            self.foo = a1
            self.bar = a2
            ...
            ...
    
        def compute1(self):
            # something involving self.foo
    
        def compute2(self):
            # something involving self.bar
    a = A()
    a.add(B(a.foo, a.bar, ...))
    a.add(B(a.foo, a.bar, ...))
    
  • 将A实例的选定属性传递给B的构造函数
    class A(object):
        def add(self, b):
            self.list_bs.append(b)
    
    class B(object):
        __init__(self, a, ...):
            self.a = a
            ...
            ...
    
        def compute1(self):
            # something involving self.a.foo
    
        def compute2(self):
            # something involving self.a.bar
    
    a = A()
    a.add(B(a, ...))
    a.add(B(a, ...))
    
    class A(object):
        def add(self, b):
            self.list_bs.append(b)
    
    class B(object):
        def __init__(self, a1, a2, ...):
            self.foo = a1
            self.bar = a2
            ...
            ...
    
        def compute1(self):
            # something involving self.foo
    
        def compute2(self):
            # something involving self.bar
    a = A()
    a.add(B(a.foo, a.bar, ...))
    a.add(B(a.foo, a.bar, ...))
    
  • 触发从A请求A属性的所有计算,即使它们与B更相关
    def class A(object):
        def add(self, b):
            b.compute1(self.foo)
            b.compute2(self.bar)
            self.list_bs.append(b)
    
    class B(object):
        def compute1(self, a1):
            # something involving a1
    
        def compute2(self, a2):
            # something involving a2
    
  • 挖沟A并将其属性用作B的类属性
    class B:
        foo = a1
        bar = a2
    
        def compute1(self):
            # something involving B.foo
    
        def compute2(self):
            # something involving B.bar
    
  • 我是错过了什么,还是想得太多了?以下哪个选项最轻/最快?
    选项1和2感觉像是大量的复制,即使只是参考。选项3感觉可能很难维持。选项4会让我将一些与B无关的A方法合并到B中,所以我不是一个大粉丝。

    我有时更喜欢将逻辑与数据容器分开(我不是说这是更快也不是更好的方法),特别是当涉及到对不同变量/状态的操作时。在这种情况下,我会考虑使用3个类而不是一个类,所以数据与逻辑保持分离。如果您正在处理的数据很简单,那么这可能很简单,但除此之外:

    class A(object):
        def __init__(self, foo, bar):
            self.foo = foo
            self.bar = bar
            
    
    class B(object):
        def __init__(self, ):
            # whatever_you need
    
    # optionally, if you really like classes, 
    # you can also think about wrapping the list in his own class:
    class WrapperB():
        def __init__(self):
          self.b_list = []
    
        def add(b: B):
           self.b_list.append(b)
    
    class BusinessLogic()
        @staticmethod
        def compute(foo, bar, b_list: WrapperB or list):
           # whatever you need
    
    假设你没有2个词条(A和B),但更多的是:我认为逻辑分离是一个可以考虑的选项。 编辑:
    正如所指出的,一个只有一个静态方法的类实际上不是一个“类”(从这个意义上说,您不需要为一个静态方法构建一个类)。在这种情况下,您可以考虑实现一个简单的函数。在本例中,我使用了一个类,只是因为如果您需要更多的逻辑,您可以扩展它。

    如果您可以这样做,选项2似乎是最干净的。每个引用是8个字节,没什么大不了的。如果选择1真的有那么大的意义,那么你只需要多做一次参考就可以成功。你真的内存有限吗?因为那时你可能只需要使用
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。我不知道吃角子老虎,谢谢你的指点!具有单个静态方法的类不应是类。它应该只是函数,但我同意,这可能是你想要的基本重构。包装器绝对有意义。我会想办法解决一下,但它应该能解决问题。