假设你有一个基类A,这个类由B和C重新实现。
假设还有一个类方法A.derived()
,它告诉你哪些类重新实现了A,因此返回[B,C],如果你以后有class D(A): pass
或class D(B): pass
,那么现在{{1}返回[B,C,D]。
您如何实施方法A.derived()
?除非你使用元类,否则我觉得这是不可能的。您可以使用标准机制仅从子级到父级遍历继承树。要使链接处于另一个方向,您必须“手动”保留它,这意味着重写传统的类声明机制。
答案 0 :(得分:18)
如果您将类定义为新样式类(object
的子类),那么这是可能的,因为子类保存在__subclasses__
中。
class A(object):
def hello(self):
print "Hello A"
class B(A):
def hello(self):
print "Hello B"
>>> for cls in A.__subclasses__():
... print cls.__name__
...
B
我不确切知道何时引入或者是否有任何特殊考虑因素。但是,它确实可以在函数中声明子类:
>>> def f(x):
... class C(A):
... def hello(self):
... print "Hello C"
... c = C()
... c.hello()
... print x
... for cls in A.__subclasses__():
... print cls.__name__
...
>>> f(4)
Hello C
4
B
C
但是,您需要注意,在运行类定义之前,解释器不知道它们。在上面的示例中,C
在执行函数f
之前不会被识别为A的子类。但是无论如何,每次python类都是一样的,因为我认为你已经知道了。
答案 1 :(得分:3)
鉴于对子类的讨论,那么实现可能如下所示:
class A(object):
@classmethod
def derived(cls):
return [c.__name__ for c in cls.__subclasses__()]
修改:您可能还想查看此answer稍微不同的问题。
答案 2 :(得分:2)
这是另一个实现,它将使用缩进以递归方式打印出所有子类。
def findsubclass(baseclass, indent=0): if indent == 0: print "Subclasses of %s are:" % baseclass.__name__ indent = indent + 1 for c in baseclass.__subclasses__(): print "-"*indent*4 + ">" + c.__name__ findsubclass(c, indent)