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

时间:2017-02-19 11:01:41

标签: python python-2.7 python-3.x inner-classes metaclass

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

<!DOCTYPE html>
<html>
<head>
<style>
body {
   width: 5000px;
   height: 5000px;
}
</style>
</head>
<body>

<p>Click the button to scroll</p>

<button onclick="scrollWin()">Click me to scroll</button><br><br>

<script>
function scrollWin() {
    window.scrollTo(0, 1000);
}
</script>

</body>
</html>

我使用嵌套类来创建某种层次结构,并提供一种实现解析器功能的简洁方法。

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

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'

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

2 个答案:

答案 0 :(得分:2)

我设法使用以下方法获取内部类对象的列表:

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

有效,但我不确定是否直接使用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__个实例,并且似乎可以在Python 2和3中移植。

答案 1 :(得分:1)

首先:我无法看到嵌套类如何对您有用。获得f Foo的实例后,您是否意识到f.Barf.AnotherBar将是所有实例的同一对象?也就是说 - 您无法在f上记录f.Bar上的任何特定属性,例如f.Bar.speed - 或者它将与另一个实例g.Bar.speed中的属性发生冲突。< / p>

要克服这一点,实际上,唯一有意义的是,您需要将BarAnotherBar的实例附加到实例f。这些实例通常无法在类主体上声明 - 您必须在Foo的__init__方法中创建它们。

Bar和AntherBar唯一能做的就是:(1)有很多类和静态方法,然后它们只作为名称空间。

或者,如果SuperBar或其自身的元类实现描述符协议 - https://docs.python.org/3/reference/datamodel.html#implementing-descriptors - 但是如果superbar本身将实现描述符协议,那么你会好得多(通过使用__get____set__方法)并附加到Foo的正文中,您拥有这些类的实例,而不是类本身。

那就是说,你带来了使用__dict__来获取内部类的解决方案:如果Foo本身从也具有嵌套类的其他类继承,那么它将无法工作。永远不会搜索Foo的超类。您可以使用方法查看Foo&#39; __mro__上的所有类,或者只使用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

(如果你想让它适用于像Foo这样没有共享基础的所有类,那么当它被声明为类方法时,相同的代码也可以工作 - 而且,SuperBar可以如果您有多个嵌套类层次结构,则为此函数的参数。)

现在你有了这个,我们恳请你提出其他问题,说明你想要做什么 - 并阅读&#34;描述符&#34; - 甚至&#34;属性&#34;。真的:人们可以想到嵌套的子类很少使用。