如何知道父母的所有派生类?

Ste*_*ini 19 python

假设你有一个基类A,这个类由B和C重新实现.假设还有一个类方法A.derived()告诉你哪些类重新实现了A,因此返回[B,C],如果你以后有class D(A): pass或者class D(B): pass,现在A.derived()返回[B,C,D].

你会如何实现这个方法A.derived()?除非你使用元类,否则我觉得这是不可能的.您可以使用标准机制仅从子级到父级遍历继承树.要使链接处于另一个方向,您必须"手动"保留它,这意味着重写传统的类声明机制.

Han*_*rén 19

如果将类定义为新样式类(子类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
Run Code Online (Sandbox Code Playgroud)

我不确切知道何时引入或者是否有任何特殊考虑因素.但是,它确实可以在函数中声明子类:

>>> 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
Run Code Online (Sandbox Code Playgroud)

但是,您需要注意,在运行类定义之前,解释器不知道它们.在上面的示例中,在执行C函数之前,不会将其识别为A的子类f.但是无论如何这对于python类来说都是一样的,因为我认为你已经知道了.

  • 抓一下我在之前的评论中所说的内容 - 我刚刚检查过,它已被添加到3.x的文档中,并在Jython 2.5中实现,所以我猜它现在已经正式发布了.我没有安装IronPython,因此无法评论它是否已实现. (6认同)
  • 好的,将来参考的附加说明:`__subclasses__`确实__not__遍历整个树,只有直接重新实现者.但是,定义一个方法`A.derived()`以便遍历整个树是相对容易的. (3认同)
  • `__subclasses__`方法是一个未记录的实现细节,因此可能会在未来的Python版本中删除.它也没有在其他版本的Python中实现,例如Jython和IronPython.小心使用. (2认同)