解析python文件以查找具有特定标签的类

Noa*_*sur 2 python parsing class

我有一个 python 文件,里面有很多类。该文件看起来像这样:

some code, functions and stuff...
class A():
     some code...
@label
class B(A):
     some code...
@label
class C(A):
    some code...
class D(A):
    some code...
some extra code...
Run Code Online (Sandbox Code Playgroud)

我想要做的是列出所有在声明之前具有@label 的类,即在本例中:[B,C]。(如果重要的话,这将发生在另一个文件中)

到目前为止,我尝试将文件解析为常规文本文件(使用 read() 和其他内容),但我得到的是类名称列表,而不是类本身,即 (['B',' C']),我不知道下一步该怎么做。我真的希望有一种更优雅的方式。获得该类列表后,我的下一步是为每个类激活它们都具有的特定功能。这就是为什么类的名称对我来说还不够。

Mar*_*ers 5

您有两个选择:

  • 使用该tokenize模块查找token.OP具有值@token.NAME标记,后跟标记 forlabel和,在换行标记之后,class。这是最轻的。

  • 使用ast模块将源解析成树,然后使用ast.walk()函数,寻找ast.ClassDef对象。如果对象有属性中的ast.Name对象,id == 'label'decorator_list可以记录该name属性。

后者可能是最简单的:

import ast

def labelled_classnames(source):
    module = ast.parse(source)
    for node in ast.walk(module):
        if not isinstance(node, ast.ClassDef):
            continue
        if any(isinstance(n, ast.Name) and n.id == 'label' 
               for n in node.decorator_list):
            yield node.name
Run Code Online (Sandbox Code Playgroud)

演示:

>>> demosource = '''
... class A():
...     pass
...
... @label
... class B(A):
...     pass
...
... @label
... class C(A):
...     pass
...
... class D(A):
...     pass
... '''
>>> list(labelled_classnames(demosource))
['B', 'C']
Run Code Online (Sandbox Code Playgroud)