在给定的 Python 文件中获取 类 的列表
Getting the list of classes in a given Python file
我的目标是获取给定 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) 中查找 class 语句。
基本上你可以解析文件,这样你就可以获得 class 声明语句。
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 语句。
这更符合您当前的方法,但有点简陋。
您可以查找由您正在查看的文件导入的内容,并 select 从语句 (Python easy way to read all import statements from py module) 中导出导入内容,并确保导入的内容中的 none 稍后显示:
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)
请注意,这目前无法区分导入的 classes 和导入的函数,但目前应该可以使用。
我的目标是获取给定 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) 中查找 class 语句。
基本上你可以解析文件,这样你就可以获得 class 声明语句。
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 语句。
这更符合您当前的方法,但有点简陋。 您可以查找由您正在查看的文件导入的内容,并 select 从语句 (Python easy way to read all import statements from py module) 中导出导入内容,并确保导入的内容中的 none 稍后显示:
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)
请注意,这目前无法区分导入的 classes 和导入的函数,但目前应该可以使用。