How can I get a list of all classes within current module in Python?
我已经看到很多人从模块中提取所有类的例子,通常是这样的:
1 2 3 4 5 6 7 8 9 10 11 | # foo.py class Foo: pass # test.py import inspect import foo for name, obj in inspect.getmembers(foo): if inspect.isclass(obj): print obj |
真棒。
但我无法找到如何从当前模块中获取所有类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # 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() |
这可能是非常明显的事情,但我找不到任何东西。 谁能帮我吗?
试试这个:
1 2 | import sys current_module = sys.modules[__name__] |
在您的上下文中:
1 2 3 4 5 | import sys, inspect def print_classes(): for name, obj in inspect.getmembers(sys.modules[__name__]): if inspect.isclass(obj): print(obj) |
甚至更好:
1 | clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass) |
因为
关于什么
1 2 | g = globals().copy() for name, obj in g.iteritems(): |
?
我不知道是否有"正确"的方法,但你的代码片段在正确的轨道上:只需将
我能够从内置的
1 2 3 4 5 6 7 8 9 | # 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) |
虽然,它确实看起来像一个毛球:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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'] ) )) |
1 2 | import pyclbr print(pyclbr.readmodule(__name__).keys()) |
请注意,stdlib的Python类浏览器模块使用静态源分析,因此它仅适用于由真实
如果你想拥有属于当前模块的所有类,你可以使用:
1 2 3 4 | 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的答案并且您在模块上导入了其他类,那么这些类也将被导入。
这就是为什么
谓词是一个函数(可调用),它返回一个布尔值。
另一个适用于Python 2和3的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #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() |
这是我用来获取当前模块中定义的所有类(即未导入)的行。根据PEP-8,它有点长,但您可以根据需要更改它。
1 2 3 4 5 | import sys import inspect classes = [name for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isclass) if obj.__module__ is __name__] |
这会为您提供类名列表。如果你想要类对象本身,只需保留obj。
1 2 | classes = [obj for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isclass) if obj.__module__ is __name__] |
这在我的经验中更有用。
我认为你可以做这样的事情。
1 2 3 4 5 6 7 | class custom(object): __custom__ = True class Alpha(custom): something = 3 def GetClasses(): return [x for x in globals() if hasattr(globals()[str(x)], '__custom__')] print(GetClasses())` |
如果你需要自己的课程