获取函数签名

本教程将讨论使用Python快速获得函数调用细节的几种方法。这在分析大型代码库时特别有用,一目了然地弄清一个函数在做什么变得困难。

对于这个确切的问题,我们有更聪明的解决方案,而不是在代码中来回走动,使用signature() 函数和装饰器。

使用signature() 来获取Python中的函数调用细节

获得这些信息的最简单的方法是使用inspect.signature() 函数。Python 3.5以上版本的文档推荐使用这个函数。

inspect.signature() 接受各种可调用程序。这包括函数、类和 对象。functools.partial()

该函数返回可调用对象的注解。如果不能提供签名,该函数会引发一个ValueError ;如果对象类型不被支持,它会引发一个TypeError

示例代码:

import inspect
def foo(x, y, a="anything"):
	pass
print(inspect.signature(foo))

它应该在你的终端上打印出以下内容。

(x, y, a="anything")

在Python中使用装饰器来获取函数调用细节

Python中的函数有一些属性,我们可以利用。在这些属性中,__code__

__code__ 属性进一步有我们可以使用的属性。下面,你可以找到它们中的每一个,解释它们的作用。

在这下面,我们将包括一个代码片段,以编写你的函数,可以执行这个任务。我们使用__name__ 属性来获取函数名称。

  1. co_varnames 返回传递给函数的参数的名称和函数内部使用的局部变量的一个元组。

  2. co_argcount 返回参数的数量。然而,这个计数不包括仅有关键字的参数 ( ), , 和 。kwargs *args **args

    我们在我们的代码段中包含了一个打印所有这些参数的方法。

def get_func_dets(func):
	# the point of using argcount is to ensure we only get
	argument_names = func.__code__.co_varnames[:func.__code__.co_argcount]
	func_name = func.__name__
	# getting variable length arguments and keyword arguments
	def inner_fun(*args, **kwargs):
		print(func_name, "(", end = "")
		print(", ".join('%s = %r' % ent
			for ent in zip(argument_names, args[:len(argument_names)])), end=", ")
		print("args = ", list(args[len(argument_names):]), end=",")
		print("kwargs =", kwargs, end="")
		print(")")
	return inner_func