我正在编写一个包含几个嵌套类的小型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方式获取内部类列表的推荐方法是什么?
答案 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.Bar
和f.AnotherBar
将是所有实例的同一对象?也就是说 - 您无法在f
上记录f.Bar
上的任何特定属性,例如f.Bar.speed
- 或者它将与另一个实例g.Bar.speed
中的属性发生冲突。< / p>
要克服这一点,实际上,唯一有意义的是,您需要将Bar
和AnotherBar
的实例附加到实例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__
上的所有类,或者只使用dir
和issubclass
:
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;。真的:人们可以想到嵌套的子类很少使用。