Класс может содержать экземпляр себя как контейнер данных?

Класс Python может содержать экземпляр себя, поскольку контейнер данных может быть похожим на это?

class A:
    def __init__(self, val):
        self.a = A(val)
        self.val = val

aa = A(2) 
#this will cause RuntimeError: maximum recursion depth exceeded

Моя цель использует этот класс в качестве контейнера данных, содержат копию внутри если это когда это быть inited для сокращения deepcopy действия. Это может используемый в качестве цепочки "отмены", дают шанс получить значение init val, когда это необходимо.

Действительно ли это возможно для такого действия?

7
задан martineau 5 January 2019 в 08:23
поделиться

2 ответа

Это не сработает по уже указанной причине:

  1. Python видит A(2) и вызывает A.__init__.
  2. A.__init__ вызывает A(val).
  3. A(val) вызывает A.__init__.
  4. GOTO 2

Я предполагаю, что вы делаете это для того, чтобы у вас был лог того, что было val; то есть, если через некоторое время вы решите, что хотите, чтобы val было 3, вы не выбросите исходное значение 2. Как насчет:

Код

class A( object ):
    @property
    def val( self ):
        return self.history[ -1 ]

    @val.setter
    def val( self, value ):
        self.history.append( value )

    def __init__( self, val ):
        self.history = [ ]
        self.val = val

Объяснение

  • A( object ): классы теперь должны наследоваться от object. Просто потому, что, по сути.
  • @property: это говорит python, что каждый раз, когда мы запрашиваем A.val, он должен вызывать A.val() и возвращать результат. Это декоратор; для получения дополнительной информации обратитесь к встроенной функции property.
  • @val.setter: это похоже на то, что описано выше, но говорит Python, что каждый раз, когда мы пытаемся присвоить A.val, он должен вызывать следующую функцию вместо этого. Вместо того чтобы присвоить A.val, она добавляет значение в список истории.
7
ответ дан 6 December 2019 в 15:17
поделиться

Ну, у класса в self.a также есть self.a, и так далее без конца. Я не уверен, что понимаю цель того, что вы делаете, но вы можете попробовать что-то вроде этого:

class A:
    def __init__(self, val, copy = True):
        if copy:
            self.a = A(val, False)
        self.val = val
1
ответ дан 6 December 2019 в 15:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: