获取派生类的所有__slots__

22 投票
2 回答
4849 浏览
提问于 2025-04-16 21:41

我需要把一个实例的所有槽位初始化为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 个回答

12

你想要遍历每一个类在 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)
17

首先,这个内容是关于

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

要创建一个列表,这个列表里包含了类B或者它的任何父类中的所有元素,也就是那些在__slots__里定义的元素,可以这样做:

from itertools import chain
slots = chain.from_iterable(getattr(cls, '__slots__', []) for cls in B.__mro__)

撰写回答