如何获得Python中当前模块中的所有类的列表?
我已经看到很多人从一个模块中提取所有类的例子,通常是这样的:
# foo.py class Foo: pass # test.py import inspect import foo for name, obj in inspect.getmembers(foo): if inspect.isclass(obj): print obj
真棒。
但是我不知道如何从当前模块中获取所有的类。
# foo.py import inspect class Foo: pass def print_classes(): for name, obj in inspect.getmembers(???): # what do I do here? if inspect.isclass(obj): print obj # test.py import foo foo.print_classes()
这可能是很明显的,但我一直没有find任何东西。 谁能帮我吗?
尝试这个:
import sys current_module = sys.modules[__name__]
在你的情况下:
import sys, inspect def print_classes(): for name, obj in inspect.getmembers(sys.modules[__name__]): if inspect.isclass(obj): print(obj)
甚至更好:
clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass)
因为inspect.getmembers()
需要一个谓词。
关于什么
g = globals().copy() for name, obj in g.iteritems():
?
我不知道是否有一个“正确”的方式来做到这一点,但是你的代码片段是正确的:只需要添加import foo
到foo.py,做inspect.getmembers(foo)
,它应该可以正常工作。
import pyclbr print(pyclbr.readmodule(__name__).keys())
请注意,stdlib的Python类浏览器模块使用静态源分析,所以它只适用于由真实的.py
文件支持的模块。
我能够从getattr
中join的dir
获得所需的全部内容。
# Works on pretty much everything, but be mindful that # you get lists of strings back print dir(myproject) print dir(myproject.mymodule) print dir(myproject.mymodule.myfile) print dir(myproject.mymodule.myfile.myclass) # But, the string names can be resolved with getattr, (as seen below)
虽然,它看起来像一个毛球:
def list_supported_platforms(): """ List supported platforms (to match sys.platform) @Retirms: list str: platform names """ return list(itertools.chain( *list( # Get the class's constant getattr( # Get the module's first class, which we wrote getattr( # Get the module getattr(platforms, item), dir( getattr(platforms, item) )[0] ), 'SYS_PLATFORMS' ) # For each include in platforms/__init__.py for item in dir(platforms) # Ignore magic, ourselves (index.py) and a base class. if not item.startswith('__') and item not in ['index', 'base'] ) ))
另一个在Python 2和3中工作的解决scheme:
#foo.py import sys class Foo(object): pass def print_classes(): current_module = sys.modules[__name__] for key in dir(current_module): if isinstance( getattr(current_module, key), type ): print(key) # test.py import foo foo.print_classes()
如果你想拥有属于当前模块的所有类,你可以使用这个:
import sys, inspect def print_classes(): is_class_member = lambda member: inspect.isclass(member) and member.__module__ == __name__ clsmembers = inspect.getmembers(sys.modules[__name__], is_class_member)
如果您使用Nadia的答案,并且您正在导入模块上的其他类,那么这些类也将被导入。
所以这就是为什么member.__module__ == __name__
被添加到is_class_member
使用的谓词。 这个语句检查这个类是否真的属于这个模块。
谓词是一个函数(可调用的),它返回一个布尔值。