46

我已经看到了以下问题,但它并没有完全让我到达我想要的地方:如何在 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和?AnotherClassYetAnotherClass

4

5 回答 5

25

检查__module__类的属性以找出它是在哪个模块中定义的。

于 2011-04-02T01:54:38.213 回答
13

对于回答这么老的问题,我深表歉意,但我对使用该解决方案的检查模块感到不舒服。我在某处读到在生产中使用不安全的地方。

将模块中的所有类初始化为列表中的无名对象

请参阅Antonis Christofides 评论以回答 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)
于 2014-02-04T21:33:07.383 回答
9

您可能还想考虑使用标准库中的“Python 类浏览器”模块:http: //docs.python.org/library/pyclbr.html

由于它实际上并没有执行有问题的模块(而是进行天真的源代码检查),因此它不太正确理解一些特定的技术,但是对于所有“正常”类定义,它将准确地描述它们。

于 2011-04-02T03:14:06.550 回答
8

我使用了以下内容:

# 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)

我不想在其中输入当前模块名称

于 2011-11-11T11:58:41.687 回答
2
from pyclbr import readmodule

clsmembers = readmodule(__name__).items()
于 2017-01-19T03:48:48.497 回答