在类B的实例中存储类A的实例

Fre*_*ter 1 python oop

我有一个问题,更多的是关于OOP,而不是特定于python.

是否可以在没有特定方法的情况下,在ClassB的实例中存储ClassA的实例,即通过某种继承.

例如:假设我有一个Model class和一个Variable class

class Model():
    def __init__(self):
        self.vars = []

    def _update_vars(self,Variable):
        self.vars.append(Variable)

class Variable(Model):
    def __init__(self,**kwargs):
        self.__dict__.update(kwargs)
Run Code Online (Sandbox Code Playgroud)

现在可以_update_vars在创建变量实例时调用.

所以,如果我做这样的事情:

mdl = Model()
varA = Variable(...)
varB = Variable(...)
Run Code Online (Sandbox Code Playgroud)

mdl.vars现在将包括varAvarB.

我知道通过将变量作为参数传递给Model的"公共"方法,我可以很容易地做到这一点.所以我不是在寻找

mdl.update_vars(varA)

所以我的两个问题是:

  1. 这可能吗?
  2. 如果是的话:这是非常非标准的OOP编程吗?

谢谢你的帮助!

r.o*_*ook 5

这不是类继承应该如何工作.如果子类要在父类中使用大量的属性/方法,您只想继承一些东西.如果子类具有明显不同的结构,则它应该是它自己的类.

在任何一种情况下,正如@jasonharper所提到的,在某些时候你需要指出哪个Variable实例属于哪个Model实例,所以你可能会得到类似这样的东西:

varA = Variable(mdl, ...)
# or this
mdl.varA = Variable(...)
Run Code Online (Sandbox Code Playgroud)

使用第一种方法,您将在您的Variable类上维护该方法:

class Foo:
    def __init__(self):
        self.vars = []

class Bar:
    def __init__(self, foo_instance, **kwargs):
        foo_instance.vars.append(self)

f = Foo()
b = Bar(f, hello='hey')
f.vars
# [<__main__.Bar object at 0x03F6B4B0>]
Run Code Online (Sandbox Code Playgroud)

使用第二种方法,您可以在每次添加Variable实例list时将其附加到:

class Foo:
    def __init__(self):
        self.vars = []
    def __setattr__(self, name, val):
        self.__dict__.update({name: val})
        if not name == 'vars':  # to prevent a recursive loop
            self.vars.append(val)

f = Foo()
f.vars
# []

f.a = 'bar'
f.vars
# ['bar']
Run Code Online (Sandbox Code Playgroud)

当然,更简单的方法是直接查看__dict__每次您想要的内容vars:

class Bar:
    @property
    def vars(self):
        # Or you can return .items() if you want both the name and the value
        return list(self.__dict__.values())

b = Bar()
b.a = 'hello'
b.vars
# ['hello']
Run Code Online (Sandbox Code Playgroud)

即使您使用自己的类实例分配了属性,这两种方法也会一样.