我的目标是获取给定 Python 文件中定义的列表类。
关注此link ,我已经实现了以下内容:
文件b.py:
import imp
import inspect
module = imp.load_source("__inspected__", './a.py')
class_members = inspect.getmembers(module, inspect.isclass)
for cls in class_members:
class_name, class_obj = cls
member = cls[1]
print(class_name)
文件a.py:
from c import CClass
class MyClass:
name = 'Edgar'
def foo(self, x):
print(x)
文件c.py:
c_var = 2
class CClass:
name = 'Anna'
我对这个实现有两个问题。
首先,如is mentioned in the post ,导入模块的类也会被打印出来。我不明白如何排除它们
其次,看起来 imp
文件已被贬值,取而代之的是 importlib
,但文档似乎很粗略。我不知道如何重构我的解决方案。有什么提示吗?
最佳答案
因此,要像使用 imp
一样使用 importlib
,您可以查看以下内容:Python 3.4: How to import a module given the full path?
你会得到类似下面的内容:
import importlib.machinery
import inspect
module = importlib.machinery.SourceFileLoader("a", './a.py').load_module()
class_members = inspect.getmembers(module, inspect.isclass)
解决方案#1:在抽象语法树 (AST) 中查找类语句。
基本上,您可以解析该文件,以便获得类声明语句。
import ast
def get_classes(path):
with open(path) as fh:
root = ast.parse(fh.read(), path)
classes = []
for node in ast.iter_child_nodes(root):
if isinstance(node, ast.ClassDef):
classes.append(node.name)
else:
continue
return classes
for c in get_classes('a.py'):
print(c)
解决方案 #2:查看导入并忽略 import from 语句。
这更符合您当前的方法,但有点卡顿。 您可以查找您正在查看的文件导入的内容,并选择导入语句 ( Python easy way to read all import statements from py module ),并确保导入的内容不会稍后出现:
import ast
from collections import namedtuple
Import = namedtuple("Import", ["module", "name", "alias"])
def get_imports(path):
with open(path) as fh:
root = ast.parse(fh.read(), path)
for node in ast.iter_child_nodes(root):
if isinstance(node, ast.Import):
# We ignore direct imports
continue
elif isinstance(node, ast.ImportFrom):
module = node.module.split('.')
else:
continue
for n in node.names:
yield Import(module, n.name.split('.'), n.asname)
imported = set()
for imp in get_imports('a.py'):
imported_classes.add(imp.name[0] if not imp.alias else imp.alias)
然后你就可以过滤掉你看到的导入的东西。
for c in class_members:
class_name, class_obj = c
member = c[1]
if class_name not in imported:
print(class_name)
请注意,当前不区分导入的类和导入的函数,但现在应该可以使用。
关于python - 获取给定 Python 文件中的类列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69603518/