Python — Получение класса типа из импортированного модуля

#python

#python

Вопрос:

Я пытаюсь импортировать класс из файла с динамическим именем. Вот мой импортер файлов:

 def get_channel_module(app, method):
    mod_name = 'channel.%s.%s' % (app, method)
    module = __import__(mod_name, globals(), locals(), [method])
    return module
  

При этом импортируется конкретный файл python, например, some_file.py , который выглядит следующим образом:

 class SomeClassA(BaseClass):
    def __init__(self, *args, **kwargs):
        return

class SomeClassB():
    def __init__(self, *args, **kwargs):
        return
  

Что я хочу сделать, так это вернуть только класс, который расширяет BaseClass из импортированного файла, поэтому в данном случае SomeClassA. Есть ли какой-либо способ сделать это?

Ответ №1:

Вы можете сделать это, проверив символы в вашем модуле с помощью issubclass :

 def get_subclass(module, base_class):
    for name in dir(module):
        obj = getattr(module, name)
        try:
            if issubclass(obj, base_class):
                return obj
        except TypeError:  # If 'obj' is not a class
            pass
    return None
  

Ответ №2:

После того, как вы импортировали свой модуль, выполните итерацию в его пространстве имен в поисках объектов класса, которые являются подклассами BaseClass.

 klasses = [c for c in module.__dict__.values() if isinstance(c, type)]
base_subclasses = [c for c in klasses if issubclass(c, BaseClass]
## or as a single list comprehension
base_subclasses = [c for c in module.__dict__.values() if isinstance(c, type) and issubclass(c, BaseClass)]
  

Комментарии:

1. Который в основном совпадает с ответом, предоставленным @Ferdinand Beyer

2. isinstance(c, type) не работает с классами старого стиля. Вместо этого следует использовать inspect.isclass(c) . Или, возможно, даже klasses = inspect.getmembers(module, inspect.isclass) .