Как получить все классы, определенные в модуле, но не импортированные? - PullRequest
40 голосов
/ 02 апреля 2011

Я уже видел следующий вопрос, но он не совсем понял, где я хочу: Как я могу получить список всех классов в текущем модуле в Python?

В частности, я не хочу импортировать классы, например если бы у меня был следующий модуль:

from my.namespace import MyBaseClass
from somewhere.else import SomeOtherClass

class NewClass(MyBaseClass):
    pass

class AnotherClass(MyBaseClass):
    pass

class YetAnotherClass(MyBaseClass):
    pass

Если я использую clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass), как предполагает принятый ответ в связанном вопросе, он возвращает MyBaseClass и SomeOtherClass в дополнение к 3, определенным в этом модуле.

Как я могу получить только NewClass, AnotherClass и YetAnotherClass?

Ответы [ 5 ]

24 голосов
/ 02 апреля 2011

Проверьте атрибут __module__ класса, чтобы узнать, в каком модуле он был определен.

12 голосов
/ 05 февраля 2014

Я прошу прощения за ответ на такой старый вопрос, но я не чувствовал себя комфортно, используя модуль проверки для этого решения. Я читал где-то, что было небезопасно для использования в производстве.

Инициализировать все классы в модуле в безымянные объекты в списке

См. Комментарий Антониса Христофидеса к ответу 1 .

Я получил ответ для проверки, является ли объект классом из Как проверить, является ли переменная классом или нет?

Так что это мое решение без проверки

def classesinmodule(module):
    md = module.__dict__
    return [
        md[c] for c in md if (
            isinstance(md[c], type) and md[c].__module__ == module.__name__
        )
    ]

classesinmodule(modulename)
7 голосов
/ 11 ноября 2011

Я использовал следующее:

# Predicate to make sure the classes only come from the module in question
def pred(c):
    return inspect.isclass(c) and c.__module__ == pred.__module__
# fetch all members of module __name__ matching 'pred'
classes = inspect.getmembers(sys.modules[__name__], pred)

Я не хотел вводить имя текущего модуля в

7 голосов
/ 02 апреля 2011

Вы также можете рассмотреть возможность использования модуля "Python class browser" в стандартной библиотеке: http://docs.python.org/library/pyclbr.html

Так как он фактически не выполняет рассматриваемый модуль (вместо этого он выполняет наивную проверку исходного кода)Есть некоторые специфические приемы, которые он не совсем правильно понимает, но для всех «нормальных» определений классов он точно их опишет.

2 голосов
/ 19 января 2017
from pyclbr import readmodule

clsmembers = readmodule(__name__).items()
...