Есть классовые методы. Могу ли я иметь атрибуты класса? - PullRequest
1 голос
/ 29 марта 2020

Рассмотрим фрагмент кода для базового класса Base и двух его дочерних классов ChildA и ChildB:

class Base():
    map = {}

    def __init__(self, x):
        type(self).map[x] = self

    @classmethod
    def get_state(cls, x):
        if x in cls.map:
             return cls.map[x]
        return None

class ChildA(Base):
    pass

class ChildB(Base):
    pass

При создании экземпляра a = ChildA('foo') и вызове ChildB.get_state('foo') после этого , он возвращает экземпляр ChildA.

Однако ожидаемое (или, скорее, желаемое поведение) было None. Атрибут map, кажется, присоединен к родительскому классу Base, а дочерние классы share it.

Конечно, я мог бы просто добавить атрибут Speci c к дочерние классы

class ChildA(Base):
    map = {}

class ChildB(Base):
    map = {}

, но это многословно, если у вас много дочерних классов и несколько таких атрибутов. Есть ли способ решить эту проблему с помощью наследования от Base?

1 Ответ

2 голосов
/ 29 марта 2020

Вы можете использовать хук подкласса init :

class Base:
    def __init_subclass__(cls, **kwargs):
        cls.map = {}

Демо:

>>> class ChildA(Base): 
...     ... 
...
>>> class ChildB(Base): 
...     ... 
...
>>> ChildA.map == ChildB.map == {}
True
>>> ChildA.map is ChildB.map
False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...