python获取文件中的类

1. 导入文件的方式获取文件中的类

由于工作需求,需要获得文件中的某一些类的内容。一般比较常用的方法是通过遍历文件,然后通过调用importlib包导入文件,就能获得文件中的内容,从而获取想要的类。代码如下:

for importer, package_name, is_pkg in pkgutil.walk_packages('.'):
	importlib.import_module(package_name)
	module = sys.modules[package_name]

	for cls_name, cls in inspect.getmembers(module, inspect.isclass):
		if is_want_class(cls):  
			do_something()

该方法十分简单,但是也有弊端。由于需要导入文件,因此文件中的内容都会被执行。而在一个项目中,存在着成百上千的文件,有一些代码是相斥的。如果通过这种方法获取类,轻则出现逻辑问题,重则出现异常,报错。

 

2.通过不导入文件的方式获取文件中的类名,从而过滤文件

为了防止上面说到的问题影响项目,我们不能将所有文件通通导入进来。但是换个思路,可以先通过不导入文件的方式获取文件中中存在的类名,如果存在的类名中有想要获取的类,再导入文件。通过这种方式避免导入所有文件,从而大大降低出错的可能性。

我们知道,python解释器在运行时候,对文件做了下列操作:

  1. Parse source code into a parse tree (Parser/pgen.c)
  2. Transform parse tree into an Abstract Syntax Tree (Python/ast.c)
  3. Transform AST into a Control Flow Graph (Python/compile.c)
  4. Emit bytecode based on the Control Flow Graph (Python/compile.c)

其中1,2步执行之后,会生成一棵抽象语法树,从而帮助解释器去解析代码结构。 

因此想要获得文件中的类,可以通过ast包获得生成的ast树,再通过遍历树节点的方式获得相应的内容。通过该方法,可以获得定义的变量和类名的文本信息。

在项目代码中,一般对于类的命名有特定的规范。因此需要正则表达式,可以过滤出文件中是否含有想要查找的类。代码如下:

for root, dirs, files in os.walk("."):
	for file in files:
	file_name = os.path.join(root, file)

	with open(file_name, "r") as source:
        # 将文件转化为ast树
        tree = ast.parse(source.read())
        # 获取树中的类
        class_name_list = [node.name for node in ast.walk(tree) if isinstance(node, ast.ClassDef)]
        # 这里通过正则want_pattern去匹配类,从而过滤出想要的类
        want_class_name_list = [name for name in class_name_list if re.search(want_pattern, name) is not None]

最后得到的want_class_name_list就是通过正则匹配出来的类的类名。通过判断want_class_name_list是否为空,就能知道文件中是否定义了自己想要的类。如果定义了,再用方法1获取文件中的类即可。

你可能感兴趣的:(python,后端)