如何读取函数签名及默认参数值?
给定一个函数对象,我该如何获取它的签名呢?比如,对于下面这个:
def my_method(first, second, third='something'):
pass
我想得到 "my_method(first, second, third='something')"
这样的结果。
9 个回答
15
在编程中,有时候我们需要让程序在特定的条件下执行某些操作。比如说,当用户点击一个按钮时,程序就要做出反应。这种情况下,我们会用到“事件监听器”。
事件监听器就像一个守卫,它一直在关注你指定的事件,比如鼠标点击、键盘按下等。当这些事件发生时,守卫就会立刻通知程序去执行相应的操作。
举个例子,假设你在网页上有一个“提交”按钮,你希望用户点击这个按钮后,程序能处理他们输入的数据。你可以设置一个事件监听器来监控这个按钮的点击事件。一旦用户点击了按钮,事件监听器就会触发,程序就会开始处理数据。
总之,事件监听器就是帮助我们在合适的时机做出反应的工具,让程序能够更智能地与用户互动。
#! /usr/bin/env python
import inspect
from collections import namedtuple
DefaultArgSpec = namedtuple('DefaultArgSpec', 'has_default default_value')
def _get_default_arg(args, defaults, arg_index):
""" Method that determines if an argument has default value or not,
and if yes what is the default value for the argument
:param args: array of arguments, eg: ['first_arg', 'second_arg', 'third_arg']
:param defaults: array of default values, eg: (42, 'something')
:param arg_index: index of the argument in the argument array for which,
this function checks if a default value exists or not. And if default value
exists it would return the default value. Example argument: 1
:return: Tuple of whether there is a default or not, and if yes the default
value, eg: for index 2 i.e. for "second_arg" this function returns (True, 42)
"""
if not defaults:
return DefaultArgSpec(False, None)
args_with_no_defaults = len(args) - len(defaults)
if arg_index < args_with_no_defaults:
return DefaultArgSpec(False, None)
else:
value = defaults[arg_index - args_with_no_defaults]
if (type(value) is str):
value = '"%s"' % value
return DefaultArgSpec(True, value)
def get_method_sig(method):
""" Given a function, it returns a string that pretty much looks how the
function signature would be written in python.
:param method: a python method
:return: A string similar describing the pythong method signature.
eg: "my_method(first_argArg, second_arg=42, third_arg='something')"
"""
# The return value of ArgSpec is a bit weird, as the list of arguments and
# list of defaults are returned in separate array.
# eg: ArgSpec(args=['first_arg', 'second_arg', 'third_arg'],
# varargs=None, keywords=None, defaults=(42, 'something'))
argspec = inspect.getargspec(method)
arg_index=0
args = []
# Use the args and defaults array returned by argspec and find out
# which arguments has default
for arg in argspec.args:
default_arg = _get_default_arg(argspec.args, argspec.defaults, arg_index)
if default_arg.has_default:
args.append("%s=%s" % (arg, default_arg.default_value))
else:
args.append(arg)
arg_index += 1
return "%s(%s)" % (method.__name__, ", ".join(args))
if __name__ == '__main__':
def my_method(first_arg, second_arg=42, third_arg='something'):
pass
print get_method_sig(my_method)
# my_method(first_argArg, second_arg=42, third_arg="something")
61
找到一个函数的用法最简单的方法就是用 help(function)
这个命令:
>>> def function(arg1, arg2="foo", *args, **kwargs): pass
>>> help(function)
Help on function function in module __main__:
function(arg1, arg2='foo', *args, **kwargs)
另外,在 Python 3 中,inspect
模块里新增了一个叫 signature
的方法,这个方法专门用来表示一个可调用对象的用法和它的返回值注解:
>>> from inspect import signature
>>> def foo(a, *, b:int, **kwargs):
... pass
>>> sig = signature(foo)
>>> str(sig)
'(a, *, b:int, **kwargs)'
>>> str(sig.parameters['b'])
'b:int'
>>> sig.parameters['b'].annotation
<class 'int'>
262
import inspect
def foo(a, b, x='blah'):
pass
print(inspect.signature(foo))
# (a, b, x='blah')
Python 3.5及以上版本建议使用 inspect.signature()
这个功能。