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

问题描述:

我有一个包含许多类的python文件。该文件看起来就像这样:解析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... 

我想要做的就是让所有具有@label他们的声明,即在这个例子之前类的列表:[B,C]。 (这将发生在另一个文件,如果它很重要)

我到目前为止尝试解析文件,就像它是一个普通的文本文件(与读取()和东西),但我得到的是类名称而不是类本身,即(['B','C']),我不知道下一步该怎么做。我真的希望有一个更优雅的方式。下一步,在获得班级名单之后,我将为每个班级激活他们所拥有的某种功能。这就是为什么这个班级的名字对我来说不够。

+0

看看了'ast'模块,它解析使用内置解析器蟒的蟒蛇文件。 – RecursivelyIronic

+0

另外[**'inspect' **](https://docs.python.org/2/library/inspect.html)。 –

+2

你有访问/可以更改装饰器的源代码吗? –

你有两个选择:

  • 使用tokenize module看出来token.OP令牌与价值@,其次是token.NAME令牌label和换行符令牌之后,class。这是最轻的。

  • 使用ast module将源解析为树,然后使用ast.walk()函数,查找ast.ClassDef对象。如果对象的ast.Name对象在decorator_list属性中具有id == 'label',则可以记录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 

演示:

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