Как я могу получить список всех классов в текущем модуле в Python?

Либо добавьте отсутствующую конфигурацию в настройку mockmvc, либо используйте явный режим генерации тестов и установите реальный контекст весенней загрузки

277
задан Martin Thoma 24 October 2014 в 07:06
поделиться

4 ответа

Try this:

import sys
current_module = sys.modules[__name__]

In your context:

import sys, inspect
def print_classes():
    for name, obj in inspect.getmembers(sys.modules[__name__]):
        if inspect.isclass(obj):
            print(obj)

And even better:

clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass)

Because inspect.getmembers() takes a predicate.

358
ответ дан 23 November 2019 в 02:06
поделиться

Я часто пишу утилиты командной строки, где первый аргумент предназначен для обращения к одному из многих различных классов. Например ./something.py feature command —-arguments, то, где Feature класс и command, является методом на том классе. Вот базовый класс, который делает это легким.

предположение - то, что этот базовый класс находится в каталоге вместе со всеми его подклассами. Можно затем звонить ArgBaseClass(foo = bar).load_subclasses(), который возвратит словарь. Например, если каталог похож на это:

  • arg_base_class.py
  • feature.py

, Принимающий feature.py реализации class Feature(ArgBaseClass), затем, вышеупомянутый вызов load_subclasses возвратится { 'feature' : <Feature object> }. Тот же kwargs (foo = bar) будет передан в Feature класс.

#!/usr/bin/env python3
import os, pkgutil, importlib, inspect

class ArgBaseClass():
    # Assign all keyword arguments as properties on self, and keep the kwargs for later.
    def __init__(self, **kwargs):
        self._kwargs = kwargs
        for (k, v) in kwargs.items():
            setattr(self, k, v)
        ms = inspect.getmembers(self, predicate=inspect.ismethod)
        self.methods = dict([(n, m) for (n, m) in ms if not n.startswith('_')])

    # Add the names of the methods to a parser object.
    def _parse_arguments(self, parser):
        parser.add_argument('method', choices=list(self.methods))
        return parser

    # Instantiate one of each of the subclasses of this class.
    def load_subclasses(self):
        module_dir = os.path.dirname(__file__)
        module_name = os.path.basename(os.path.normpath(module_dir))
        parent_class = self.__class__
        modules = {}
        # Load all the modules it the package:
        for (module_loader, name, ispkg) in pkgutil.iter_modules([module_dir]):
            modules[name] = importlib.import_module('.' + name, module_name)

        # Instantiate one of each class, passing the keyword arguments.
        ret = {}
        for cls in parent_class.__subclasses__():
            path = cls.__module__.split('.')
            ret[path[-1]] = cls(**self._kwargs)
        return ret
0
ответ дан 23 November 2019 в 02:06
поделиться

I don't know if there's a 'proper' way to do it, but your snippet is on the right track: just add import foo to foo.py, do inspect.getmembers(foo), and it should work fine.

14
ответ дан 23 November 2019 в 02:06
поделиться

What about

g = globals().copy()
for name, obj in g.iteritems():

?

17
ответ дан 23 November 2019 в 02:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: