0

我有一个包含 python 代码的文件。我需要检查它(无需导入或运行它,尽管编译它是可以的)。

我想获取文件中声明的类,看看它们是否派生自某个基类。

例如,

比如说在我的“foo”模块中,我定义了一个名为“Bar”的类,它派生自“Foo”类:

class Foo(object):
    pass

class Bar(Foo)
    pass

然后我有一个外部python源文件,例如:

from foo import Bar

class Baz(Bar):
    pass

我想检查源以了解该文件是否包含从我的“Foo”派生的任何类定义。

我需要解析 AST 吗?这是静态分析子类定义的正确方向吗?

4

2 回答 2

1

不编译代码的答案是使用pysmell或类似的。

鉴于:

# base.py
class Base(object):
    def __init__(self, name):
        self.name = name

class First(Base):
    def __init__(self, name="first"):
        super(First, self).__init__(name)


class Second(First):
    def __init__(self, name="second"):
        super(Second, self).__init__(name)

class Third(Second):
    def __init__(self, name="third"):
        super(Third, self).__init__(name)

t = Third()

运行pysmell base.py生成一个 PYSMELLTAGS 文件,如下所示:

{'CLASSES': {'base.Base': {'bases': ['object'],
                           'constructor': ['name'],
                           'docstring': '',
                           'methods': [],
                           'properties': ['name']},
             'base.First': {'bases': ['base.Base'],
                            'constructor': ["name='first'"],
                            'docstring': '',
                            'methods': [],
                            'properties': []},
             'base.Second': {'bases': ['base.First'],
                             'constructor': ["name='second'"],
                             'docstring': '',
                             'methods': [],
                             'properties': []},
             'base.Third': {'bases': ['base.Second'],
                            'constructor': ["name='third'"],
                            'docstring': '',
                            'methods': [],
                            'properties': []}},
 'CONSTANTS': ['base.t'],
 'FUNCTIONS': [],
 'HIERARCHY': ['base'],
 'POINTERS': {}}

我相信这将有助于 OP 实现识别从其他类派生的类的目标。

于 2013-02-02T00:00:15.760 回答
-1

我认为这样的事情就可以了,因为它只会污染x

import inspect
from tester import Test

x = __import__("something", globals={}, locals={})

for (n,v) in inspect.getmembers(x):
    if inspect.isclass(v):
        print "CLASS:", n, inspect.getmro(v)
        if Test != v and Test in inspect.getmro(v):
            print "FOUND:", n, v


 #something.py
 from tester import Test
 class SomeClass(Test): pass


 #tester.py
 class Test(object): pass

输出:

CLASS: SomeClass (<class 'something.SomeClass'>, <class 'tester.Test'>, <type 'object'>)
FOUND: SomeClass <class 'something.SomeClass'>
CLASS: Test (<class 'tester.Test'>, <type 'object'>)
于 2013-01-31T19:30:10.573 回答