假设函数a_method的定义如下
def a_method(arg1, arg2):
pass
从a_method本身开始,我怎么能得到参数名-例如,作为字符串的元组,如("arg1", "arg2")?
假设函数a_method的定义如下
def a_method(arg1, arg2):
pass
从a_method本身开始,我怎么能得到参数名-例如,作为字符串的元组,如("arg1", "arg2")?
当前回答
Python 3.5 +:
DeprecationWarning: inspect.getargspec()自Python 3.0起已弃用,请使用inspect.signature()或inspect.getfullargspec()
所以之前:
func_args = inspect.getargspec(function).args
Now:
func_args = list(inspect.signature(function).parameters.keys())
测试:
'arg' in list(inspect.signature(function).parameters.keys())
假设函数function接受参数arg,它的值为True,否则为False。
来自Python控制台的示例:
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32
>>> import inspect
>>> 'iterable' in list(inspect.signature(sum).parameters.keys())
True
其他回答
在decorator方法中,你可以这样列出原始方法的参数:
import inspect, itertools
def my_decorator():
def decorator(f):
def wrapper(*args, **kwargs):
# if you want arguments names as a list:
args_name = inspect.getargspec(f)[0]
print(args_name)
# if you want names and values as a dictionary:
args_dict = dict(itertools.izip(args_name, args))
print(args_dict)
# if you want values as a list:
args_values = args_dict.values()
print(args_values)
如果**狼对你来说很重要,那就有点复杂了:
def wrapper(*args, **kwargs):
args_name = list(OrderedDict.fromkeys(inspect.getargspec(f)[0] + kwargs.keys()))
args_dict = OrderedDict(list(itertools.izip(args_name, args)) + list(kwargs.iteritems()))
args_values = args_dict.values()
例子:
@my_decorator()
def my_function(x, y, z=3):
pass
my_function(1, y=2, z=3, w=0)
# prints:
# ['x', 'y', 'z', 'w']
# {'y': 2, 'x': 1, 'z': 3, 'w': 0}
# [1, 2, 3, 0]
检查。签名很慢。最快的方法是
def f(a, b=1, *args, c, d=1, **kwargs):
pass
f_code = f.__code__
f_code.co_varnames[:f_code.co_argcount + f_code.co_kwonlyargcount] # ('a', 'b', 'c', 'd')
Python 3.5 +:
DeprecationWarning: inspect.getargspec()自Python 3.0起已弃用,请使用inspect.signature()或inspect.getfullargspec()
所以之前:
func_args = inspect.getargspec(function).args
Now:
func_args = list(inspect.signature(function).parameters.keys())
测试:
'arg' in list(inspect.signature(function).parameters.keys())
假设函数function接受参数arg,它的值为True,否则为False。
来自Python控制台的示例:
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32
>>> import inspect
>>> 'iterable' in list(inspect.signature(sum).parameters.keys())
True
我觉得你要找的是当地人的方法
In [6]: def test(a, b):print locals()
...:
In [7]: test(1,2)
{'a': 1, 'b': 2}
对于那些像我一样正在寻找将所有参数及其值(默认值或非默认值)放入一个字典的解决方案的人,我还有另一个建议。
import inspect
def get_arguments(func, args, kwargs, is_method=False):
offset = 1 if is_method else 0
specs = inspect.getfullargspec(func)
d = {}
for i, parameter in enumerate(specs.args[offset:]):
i += offset
if i < len(args):
d[parameter] = args[i]
elif parameter in kwargs:
d[parameter] = kwargs[parameter]
else:
d[parameter] = specs.defaults[i - len(args)]
return d
现在在这样的装饰器中打印get_arguments的返回值
def a_function_decorator(func):
def inner(*args, **kwargs):
print(get_arguments(func, args, kwargs))
return func(*args, **kwargs)
return inner
把它应用到一个函数上
@a_function_decorator
def foo(a, b, c="default_c", d="default_d"):
pass
会给我们
foo(1, 2, d="eek")
# {'a': 1, 'b': 2, 'c': 'default_c', 'd': 'eek'}
foo(1, 2, "blah")
# {'a': 1, 'b': 2, 'c': 'blah', 'd': 'default_c'}
foo(1, 2)
# {'a': 1, 'b': 2, 'c': 'default_c', 'd': 'default_d'}
方法也是一样
def a_method_decorator(func):
def inner(*args, **kwargs):
print(get_arguments(func, args, kwargs, is_method=True))
return func(*args, **kwargs)
return inner
class Bar:
@a_method_decorator
def foo(self, a, b, c="default_c", d="default_d"):
pass
Bar().foo(1, 2, d="eek")
#{'a': 1, 'b': 2, 'c': 'default_c', 'd': 'eek'}
Bar().foo(1, 2, "blah")
# {'a': 1, 'b': 2, 'c': 'blah', 'd': 'default_c'}
Bar().foo(1, 2)
# {'a': 1, 'b': 2, 'c': 'default_c', 'd': 'default_d'}
它当然不是最漂亮的解决方案,但它是我见过的第一个完全符合我要求的解决方案。