Хранить экземпляр класса A в экземпляре класса B - PullRequest
0 голосов
/ 17 января 2019

У меня есть вопрос, который больше касается ООП в целом, а не конкретного Python.

Возможно хранить экземпляры ClassA в экземпляре ClassB без специального метода, то есть с помощью какого-либо наследования.

Пример: допустим, у меня есть один 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)

Теперь можно вызывать _update_vars всякий раз, когда создается экземпляр переменной.

Так что, если я сделаю что-то вроде этого:

mdl = Model()
varA = Variable(...)
varB = Variable(...)

, что mdl.vars теперь будет включать varA и varB.

Я знаю, что я мог бы легко сделать это, передав переменные в качестве аргумента "публичному" методу Model. Поэтому я не ищу

mdl.update_vars(varA)

Итак, мои два вопроса:

  1. это возможно?
  2. если да: будет ли это очень нестандартное программирование ООП?

Спасибо за вашу помощь!

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Это не так, как должно работать наследование классов. Вы хотите наследовать что-то, только если дочерний класс собирается использовать достаточное количество атрибутов / методов в родительском классе. Если дочерний класс имеет заметно отличающуюся структуру, он должен быть собственным классом.

В любом случае, как упомянуто @jasonharper, в какой-то момент вам потребуется указать направление, к которому относится экземпляр Variable, к какому экземпляру Model, так что вы, скорее всего, получите что-то вроде этого:

varA = Variable(mdl, ...)
# or this
mdl.varA = Variable(...)

При первом способе вы должны поддерживать метод в вашем 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>]

Вторым способом вы можете добавлять 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']

Конечно, более простой способ - просто смотреть прямо в __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']

Оба они будут работать одинаково, даже если вы присвоили атрибуты своим собственным экземплярам класса.

0 голосов
/ 17 января 2019

Вы можете использовать super () для этого и передать экземпляр родительскому элементу

class Model():
    vars = []

    def __init__(self, other=None):
        if other:
            self.vars.append(other)


class Variable(Model):
    def __init__(self, a):
        self.a = a
        super().__init__(self)


mdl = Model()
varA = Variable(3)
varB = Variable(4)
print(mdl.vars)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...