python - 如何获取内部 类 的列表?

python - how to get a list of inner classes?

我正在编写一个包含一些嵌套 类 的小型 Python 应用程序,如下例所示:

class SuperBar(object):
    pass

class Foo(object):
    NAME = 'this is foo'

    class Bar(SuperBar):
        MSG = 'this is how Bar handle stuff'

    class AnotherBar(SuperBar):
        MSG = 'this is how Another Bar handle stuff'

我正在使用嵌套 类 来创建某种层次结构并提供一种干净的方式来实现解析器的功能。

在某些时候,我想创建一个内部列表 类。我想要以下输出:

[<class '__main__.Bar'>, <class '__main__.AnotherBar'>]

问题是:以pythonic方式获取内部类列表的推荐方法是什么?

我设法使用以下方法获得了内部 class 个对象的列表:

import inspect

def inner_classes_list(cls):
    return [cls_attribute for cls_attribute in cls.__dict__.values()
            if inspect.isclass(cls_attribute)
            and issubclass(cls_attribute, SuperBar)]

有效,但我不确定直接使用 __dict__ 是否是一件好事。我使用它是因为它包含我需要的实际 class 实例,并且似乎可以在 Python 2 和 3 之间移植。

首先:我看不出嵌套 classes 对您有何用处。一旦你有了 Foo 的实例 f,你是否意识到 f.Barf.AnotherBar 对所有实例来说都是同一个对象?也就是说 - 您不能在 f.Bar 上记录来自 f 的任何特定属性,例如 f.Bar.speed - 否则它会与来自另一个实例 g.Bar.speed.[=35 的属性发生冲突=]

为了克服这个问题,实际上,唯一有意义的事情是,您需要将 BarAnotherBar 的实例附加到实例 f。这些实例通常不能在 class 主体上声明 - 您必须在 Foo 的 __init__ 方法上创建它们。

Bar 和 AntherBar 唯一可以做的是:(1) 有很多 class 和静态方法,然后它们只作为命名空间工作。

或者,如果 SuperBar 的元 class 或它们自己实现了描述符协议 - https://docs.python.org/3/reference/datamodel.html#implementing-descriptors - 但它们,如果 superbar 本身,你会好得多将实现描述符协议(通过 __get____set__ 方法),并附加到 Foo 的主体上,您将拥有这些 class 的 个实例 es,而不是 classes 本身。

就是说,您提出了使用 __dict__ 来获取内部 classes 的解决方案:如果 Foo 本身继承自其他 class,那将不起作用]es 也有嵌套的 classes。永远不会搜索 Foo 的 Superclasses。你可以有一种方法来查看 Foo 的 __mro__ 上的所有 classes,或者简单地使用 dirissubclass :

class Foo:
     @classmethod
     def inner_classes_list(cls):
          results = []
          for attrname in dir(cls):
              obj = getattr(cls, attrname)
              if isinstance(obj, type) and issubclass(obj, SuperBar):
                   results.append(obj)
          return results

(如果您希望它适用于所有 class 不共享公共基础的 Foo ,如果将其声明为 class 方法,则相同的代码将起作用,当然 - 此外,如果您有多个 nested-class 层次结构,SuperBar 可以作为此函数的参数。)

现在你有了这个,我们敦促你问其他问题,说明你实际想做什么 - 并阅读 "descriptors" - 甚至 "properties"。确实:嵌套的 subclasses 几乎没有什么用处。