我正在寻找一种方法来可靠地使用__slots__
获取类的所有插槽名称的列表。示例:
class A:
__slots__ = ('a',)
print(list_slots(A)) # should output ['a']
当然,list(A.__slots__)
可以完成此操作,但是不幸的是,有几件事情使这变得更加困难:
继承的广告位:
class B(A):
__slots__ = ('b',)
print(list_slots(B)) # should output ['a', 'b']
字符串:
class C:
__slots__ = 'xyz'
print(list_slots(C)) # should output ['xyz']
迭代器:
class D:
__slots__ = iter(['d'])
print(list_slots(D)) # should output ['d']
如您所见,这里有很多陷阱... list_slots
的实现是否可以正确处理所有这些情况?
答案 0 :(得分:0)
在这种情况下,我会使用inspect.ismemberdescriptor
(doc):
import inspect
class A:
__slots__ = ('a',)
class B(A):
__slots__ = ('b',)
class X(B):
__slots__ = ('c',)
class C:
__slots__ = 'xyz'
class D:
__slots__ = iter(['d'])
def get_slots(cls):
for k, v in cls.__dict__.items():
if inspect.ismemberdescriptor(v):
yield k
for b in cls.__bases__:
yield from get_slots(b)
print(list(get_slots(A)))
print(list(get_slots(B)))
print(list(get_slots(C)))
print(list(get_slots(D)))
print(list(get_slots(X)))
打印:
['a']
['b', 'a']
['xyz']
['d']
['c', 'b', 'a']
编辑1:更新了我对get_slots()
递归版本的回答
编辑2:正如Aran-Fey在评论中指出的那样,该解决方案仅在CPython中有效。