Получить все __slots__ производного класса - PullRequest
15 голосов
/ 17 июля 2011

Мне нужно инициализировать все слоты экземпляра с помощью None. Как получить все слоты производного класса?

Пример (который не работает):

class A(object):
    __slots__ = "a"

    def __init__(self):
        # this does not work for inherited classes
        for slot in type(self).__slots__:
            setattr(self, slot, None)

class B(A):
    __slots__ = "b"

Я мог бы использовать дополнительный атрибут класса, который содержит слоты (включая унаследованные) для всех классов, например

class A(object):
    __slots__ = "a"
    all_slots = "a"

    def __init__(self):
        # this does not work for inherited classes
        for slot in type(self).all_slots:
            setattr(self, slot, None)

class B(A):
    __slots__ = "b"
    all_slots = ["a", "b"]

но это кажется неоптимальным.

Любые комментарии приветствуются!

Приветствия

Jan

Ответы [ 2 ]

14 голосов
/ 17 июля 2011

Прежде всего, это

class A(object):
    __slots__ = ('a',)
class B(A):
    __slots__ =  ('b',)

Создание списка, который содержит все элементы, содержащиеся в __slots__ из B или любого из его родительских классов, будет:

from itertools import chain
slots = chain.from_iterable(getattr(cls, '__slots__', []) for cls in B.__mro__)
9 голосов
/ 17 июля 2011

Вы хотите перебрать каждый класс в MRO :

class A(object):
    __slots__ = ('x', 'y')
    def __init__(self):
        for slots in [getattr(cls, '__slots__', []) for cls in type(self).__mro__]:
            for attr in slots:
                setattr(self, attr, None)

Вы можете видеть, что это работает, как и ожидалось в производном классе:

class B(A):
    __slots__ = ('z',)

>>> b = B()

>>> b.x, b.y, b.z
<<< (None, None, None)
...