如何从 Python 对象中检索源代码?
使用 inspect 模块,您可以检索 Python 函数、方法、类或模块的源代码。以下示例演示了如何检索函数的源代码 −
示例
import inspect def my_function(x, y): return x + y source_code = inspect.getsource(my_function) print(source_code)
输出
def my_function(x, y): return x + y
此代码定义了一个简单的函数 my_function,它接受两个参数并返回这些参数的总和。然后,我们使用 inspect.getsource() 函数检索 my_function 函数的源代码,并将其存储在源代码变量中。最后,源代码输出到控制台。
inspect.getsource() 函数通过从定义函数的文件中读取函数的源代码来运行。它以字符串形式返回函数的整个源代码,包括源代码中存在的任何注释或空行。
inspect.getsourcefile() 函数还可用于检索包含函数或模块源代码的文件名。如果您需要找到包含特定函数或模块的文件,这将很有帮助。
以下示例演示了如何检索包含函数源代码的文件名 -
示例
import inspect def my_function(x, y): return x + y source_file = inspect.getsourcefile(my_function) print(source_file)
输出
/home/cg/root/79120/main.py
此代码定义与之前相同的 my function 函数,并使用 inspect.getsourcefile() 函数检索包含函数源代码的文件名。此函数以字符串形式返回文件名,而不是实际源代码。
inspect 模块提供了几个函数来检索有关 Python 对象的信息,包括其源代码。以下是一些其他示例 −
要检索类方法的源代码,请在方法本身上调用 inspect.getsource() −
示例
import inspect class MyClass: def my_method(self, x, y): return x + y source_code = inspect.getsource(MyClass.my_method) print(source_code)
输出
def my_method(self, x, y): return x + y
在此示例中,类 MyClass 有一个名为 my method 的方法,该方法接受两个参数并返回它们的总和。然后使用 inspect.getsource() 检索 MyClass.my method 方法的源代码。
要检索模块的完整源代码,请在模块本身上使用 inspect.getsource() 函数 −
示例
import inspect import my_module source_code = inspect.getsource(my_module) print(source_code)
在此示例中,我们导入 my module 模块并使用 inspect.getsource 检索其源代码。
您还可以使用 inspect.getfile 函数获取保存模块、类或函数源代码的文件的名称。与 inspect.getsourcefile 类似,此函数以字符串形式返回文件名。此示例演示如何使用 inspect.getfile 检索模块的文件名 -
示例
import inspect import my_module source_file = inspect.getfile(my_module) print(source_file)
此代码导入 my_module 模块并使用 inspect.getfile() 检索源代码文件的名称。请注意,此函数返回文件的绝对路径。
dis 模块是检索 Python 函数源代码的另一种方法。dis 模块为您提供了 Python 字节码的反汇编程序,您可以使用它来查看函数的字节码指令。通过反编译字节码,可以更全面地了解函数的运行方式,包括确切的运行顺序。
下面是一个如何使用 dis 模块检索函数的字节码指令的示例 −
示例
import dis def my_function(x, y): return x + y bytecode = dis.Bytecode(my_function) for instruction in bytecode: print(instruction)
输出
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='x', argrepr='x', offset=0, starts_line=3, is_jump_target=False) Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='y', argrepr='y', offset=2, starts_line=None, is_jump_target=False) Instruction(opname='BINARY_ADD', opcode=23, arg=None, argval=None, argrepr='', offset=4, starts_line=None, is_jump_target=False) Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=6, starts_line=None, is_jump_target=False)
在此示例中,定义了一个名为 my_function 的简单函数,该函数接受两个参数并返回它们的和。然后通过将 my_function 函数传递给 dis.Bytecode 函数 Object() { [native code] } 来创建 dis.Bytecode 对象。这让我们可以看到函数的字节码指令被拆开后的视图。然后我们可以使用 for 循环遍历这些指令并将其打印到控制台。
此代码将返回一系列 dis.Instruction 对象,它们代表函数的字节码指令。每个 dis.Instruction 对象都包含 opname(字节码指令的名称)、argval(指令的参数)和 offset(函数字节码中指令的字节偏移量)等属性。通过查看这些属性,您可以了解有关函数工作原理的所有信息。
请注意,dis 模块可能非常低级,可能不适合所有用例。但是,如果您需要彻底了解函数的运行方式,它可能是一个有用的工具。我们使用 inspect 模块的 getsource() 方法获取函数的源代码。
示例
inspect.getsource(object)
这将返回对象源代码的文本。参数可以是模块、类、方法、函数、回溯、框架或代码对象。将源代码作为单个字符串返回。如果无法检索源代码,则会生成 IOError。
如果函数是从字符串、流编译的,或者从先前编译的文件中导入的,则无法检索其源代码。
以下是我们如何导入 inspect 模块并检索给定脚本的源代码
示例
#baz.py import inspect class foo: def bar(): print ('Hello') print(inspect.getsource(foo))
输出
class foo: def bar(): print ('Hello')