python inspect.getsource 获取错误的源代码
运行这个文件 foo.py
import inspect
class Parent(object):
def source1(self):
class A(object):
def foo(self):
pass
print inspect.getsource(A)
def source2(self):
class A(object):
def bar(self, a, b, c):
pass
print inspect.getsource(A)
parent = Parent()
parent.source1()
parent.source2()
会产生这样的输出:
class A(object):
def foo(self):
pass
class A(object):
def foo(self):
pass
而我原本期待它能产生这样的输出:
class A(object):
def foo(self):
pass
class A(object):
def bar(self, a, b, c):
pass
我在测试中遇到了这个问题。我在测试方法里重复使用了 A
和 B
作为类名。我正在测试一个依赖于 inspect.getsource
的函数,但结果并不如我所愿,因为后面的测试得到了之前命名的 A
和 B
类的源代码。
2 个回答
2
这是因为 inspect.getsource
会在源文件中找到第一个匹配的 class A
。根据 Python 2.7.6 中 inspect.py
的第 545 行
,这个模式是用来查找源代码的。
pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
所以如果你一开始在代码前面定义了 class A
,就像这样:
import inspect
class A(object):
pass
class Parent(object):
def source1(self):
class A(object):
def foo(self):
pass
print 'id of A in source1 :', id(A)
print inspect.getsource(A)
def source2(self):
class A(object):
def bar(self, a, b, c):
pass
print 'id of A in source2 :', id(A)
print inspect.getsource(A)
print 'id of A in global :', id(A)
parent = Parent()
parent.source1()
parent.source2()
那么结果将会是:
id of A in global : 12512848
id of A in source1 : 12415088
class A(object):
pass
id of A in source2 : 12356672
class A(object):
pass
即使它们的对象 id
是不同的。
2
inspect.getsource这个调用其实是去解析源文件,寻找类的定义,并返回它找到的第一个符合要求的类,这个类的缩进层级是最低的。换句话说,它不会按照你想要的那样去做。
这里有一个稍微不同的方法,可以得到你想要的输出,也许能满足你的需求:
import inspect
class Parent(object):
def source1(self):
class A1(object):
def foo(self):
pass
A = A1
print inspect.getsource(A)
def source2(self):
class A2(object):
def bar(self, a, b, c):
pass
A = A2
print inspect.getsource(A)
parent = Parent()
parent.source1()
parent.source2()
类的定义仍然可以用你想要的名字(比如“A”)来引用,但在源代码中的实际定义使用了不同的名字,这样getsource就能找到它了。