如何找到给定名称的类的所有子类? [英] How to find all the subclasses of a class given its name?

查看:66
本文介绍了如何找到给定名称的类的所有子类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一种工作方法来获取从 Python 中的基类继承的所有类.

I need a working approach of getting all classes that are inherited from a base class in Python.

推荐答案

新式类(即从 object 继承而来,这是 Python 3 中的默认设置)有一个 __subclasses__ 返回子类的方法:

New-style classes (i.e. subclassed from object, which is the default in Python 3) have a __subclasses__ method which returns the subclasses:

class Foo(object): pass
class Bar(Foo): pass
class Baz(Foo): pass
class Bing(Bar): pass

以下是子类的名称:

print([cls.__name__ for cls in Foo.__subclasses__()])
# ['Bar', 'Baz']

以下是子类本身:

print(Foo.__subclasses__())
# [<class '__main__.Bar'>, <class '__main__.Baz'>]

确认子类确实将 Foo 列为它们的基类:

Confirmation that the subclasses do indeed list Foo as their base:

for cls in Foo.__subclasses__():
    print(cls.__base__)
# <class '__main__.Foo'>
# <class '__main__.Foo'>

注意,如果你想要子类,你必须递归:

Note if you want subsubclasses, you'll have to recurse:

def all_subclasses(cls):
    return set(cls.__subclasses__()).union(
        [s for c in cls.__subclasses__() for s in all_subclasses(c)])

print(all_subclasses(Foo))
# {<class '__main__.Bar'>, <class '__main__.Baz'>, <class '__main__.Bing'>}

请注意,如果尚未执行子类的类定义 - 例如,如果尚未导入子类的模块 - 则该子类尚不存在,并且 __subclasses__ 找不到了.

Note that if the class definition of a subclass hasn't been executed yet - for example, if the subclass's module hasn't been imported yet - then that subclass doesn't exist yet, and __subclasses__ won't find it.

你提到了给定它的名字".由于 Python 类是一流的对象,因此您不需要使用带有类名的字符串来代替类或类似的东西.您可以直接使用该类,而且您可能应该这样做.

You mentioned "given its name". Since Python classes are first-class objects, you don't need to use a string with the class's name in place of the class or anything like that. You can just use the class directly, and you probably should.

如果您确实有一个表示类名的字符串,并且您想找到该类的子类,那么有两个步骤:根据类名查找类,然后使用 __subclasses__ 如上.

If you do have a string representing the name of a class and you want to find that class's subclasses, then there are two steps: find the class given its name, and then find the subclasses with __subclasses__ as above.

如何从名称中找到类取决于您希望在哪里找到它.如果您希望在与尝试定位类的代码相同的模块中找到它,那么

How to find the class from the name depends on where you're expecting to find it. If you're expecting to find it in the same module as the code that's trying to locate the class, then

cls = globals()[name]

会做这项工作,或者在不太可能的情况下,您希望在当地人中找到它,

would do the job, or in the unlikely case that you're expecting to find it in locals,

cls = locals()[name]

如果类可以在任何模块中,那么您的名称字符串应包含完全限定名称 - 类似于 'pkg.module.Foo' 而不是 'Foo'.使用 importlib 加载类的模块,然后检索相应的属性:

If the class could be in any module, then your name string should contain the fully-qualified name - something like 'pkg.module.Foo' instead of just 'Foo'. Use importlib to load the class's module, then retrieve the corresponding attribute:

import importlib
modname, _, clsname = name.rpartition('.')
mod = importlib.import_module(modname)
cls = getattr(mod, clsname)

无论您如何找到该类,cls.__subclasses__() 都会返回其子类的列表.

However you find the class, cls.__subclasses__() would then return a list of its subclasses.

这篇关于如何找到给定名称的类的所有子类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆