This question already has an answer here:
这个问题在这里已有答案:
- How to find all the subclasses of a class given its name? 10 answers
如何根据名称查找类的所有子类? 10个答案
Is there any way in python to query a namespace for classes which inherit from a particular class? Given a class widget
I'd like to be able to call something like inheritors(widget)
to get a list of all my different kinds of widget.
在python中是否有任何方法可以查询从特定类继承的类的命名空间?给定一个类小部件,我希望能够调用类似继承者(小部件)的东西来获取我所有不同类型小部件的列表。
4 个解决方案
#1
46
You want to use Widget.__subclasses__()
to get a list of all the subclasses. It only looks for direct subclasses though so if you want all of them you'll have to do a bit more work:
您想使用Widget .__ subclasses __()来获取所有子类的列表。它只查找直接子类,但如果你想要所有这些,你将不得不做更多的工作:
def inheritors(klass):
subclasses = set()
work = [klass]
while work:
parent = work.pop()
for child in parent.__subclasses__():
if child not in subclasses:
subclasses.add(child)
work.append(child)
return subclasses
N.B. If you are using Python 2.x this only works for new-style classes.
注:如果您使用的是Python 2.x,则仅适用于新式类。
#2
16
You can track inheritance with your own metaclass
您可以使用自己的元类跟踪继承
import collections
class A(object):
class __metaclass__(type):
__inheritors__ = defaultdict(list)
def __new__(meta, name, bases, dct):
klass = type.__new__(meta, name, bases, dct)
for base in klass.mro()[1:-1]:
meta.__inheritors__[base].append(klass)
return klass
class B(A):
pass
class C(B):
pass
>>> A.__inheritors__
defaultdict(<type 'list'>, {<class '__main__.A'>: [<class '__main__.B'>, <class '__main__.C'>], <class '__main__.B'>: [<class '__main__.C'>]})
Anything that is inherited from A
or it's derived classes will be tracked. You will get full inheritance map when all the modules in your application are loaded.
将跟踪从A或其派生类继承的任何内容。加载应用程序中的所有模块后,您将获得完整的继承映射。
#3
2
# return list of tuples (objclass, name) containing all subclasses in callers' module
def FindAllSubclasses(classType):
import sys, inspect
subclasses = []
callers_module = sys._getframe(1).f_globals['__name__']
classes = inspect.getmembers(sys.modules[callers_module], inspect.isclass)
for name, obj in classes:
if (obj is not classType) and (classType in inspect.getmro(obj)):
subclasses.append((obj, name))
return subclasses
#4
1
You have to walk through all objects in the global namespace (globals()) and check if the related object/class is a subclass of the some other class (check the Python docs for issubclass()).
您必须遍历全局命名空间中的所有对象(globals())并检查相关对象/类是否是其他类的子类(请查看issubclass()的Python文档)。
#1
46
You want to use Widget.__subclasses__()
to get a list of all the subclasses. It only looks for direct subclasses though so if you want all of them you'll have to do a bit more work:
您想使用Widget .__ subclasses __()来获取所有子类的列表。它只查找直接子类,但如果你想要所有这些,你将不得不做更多的工作:
def inheritors(klass):
subclasses = set()
work = [klass]
while work:
parent = work.pop()
for child in parent.__subclasses__():
if child not in subclasses:
subclasses.add(child)
work.append(child)
return subclasses
N.B. If you are using Python 2.x this only works for new-style classes.
注:如果您使用的是Python 2.x,则仅适用于新式类。
#2
16
You can track inheritance with your own metaclass
您可以使用自己的元类跟踪继承
import collections
class A(object):
class __metaclass__(type):
__inheritors__ = defaultdict(list)
def __new__(meta, name, bases, dct):
klass = type.__new__(meta, name, bases, dct)
for base in klass.mro()[1:-1]:
meta.__inheritors__[base].append(klass)
return klass
class B(A):
pass
class C(B):
pass
>>> A.__inheritors__
defaultdict(<type 'list'>, {<class '__main__.A'>: [<class '__main__.B'>, <class '__main__.C'>], <class '__main__.B'>: [<class '__main__.C'>]})
Anything that is inherited from A
or it's derived classes will be tracked. You will get full inheritance map when all the modules in your application are loaded.
将跟踪从A或其派生类继承的任何内容。加载应用程序中的所有模块后,您将获得完整的继承映射。
#3
2
# return list of tuples (objclass, name) containing all subclasses in callers' module
def FindAllSubclasses(classType):
import sys, inspect
subclasses = []
callers_module = sys._getframe(1).f_globals['__name__']
classes = inspect.getmembers(sys.modules[callers_module], inspect.isclass)
for name, obj in classes:
if (obj is not classType) and (classType in inspect.getmro(obj)):
subclasses.append((obj, name))
return subclasses
#4
1
You have to walk through all objects in the global namespace (globals()) and check if the related object/class is a subclass of the some other class (check the Python docs for issubclass()).
您必须遍历全局命名空间中的所有对象(globals())并检查相关对象/类是否是其他类的子类(请查看issubclass()的Python文档)。