【问题标题】:Is there a reliable way to list all of a class's __slots__?有没有一种可靠的方法来列出一个类的所有 __slots__?
【发布时间】:2019-11-04 02:59:16
【问题描述】:

我正在寻找一种方法来可靠地获取具有__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 的实现可以正确处理所有这些情况?

【问题讨论】:

    标签: python attributes slots


    【解决方案1】:

    在这种情况下我会使用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 在 cmets 中指出的那样,此解决方案仅适用于 CPython。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2021-06-27
      • 2016-02-21
      • 1970-01-01
      • 2022-01-15
      相关资源
      最近更新 更多