了解 Python 中的函数参数
Understanding function arguments in Python
我试图了解以下有关处理函数及其参数的内容:
def print_my_arg(func, *args, **kwargs):
func(*args, **kwargs)
if 'my_arg' in kwargs:
print(' my_arg = {}'.format(kwargs['my_arg']))
def foo(call_no, my_arg='Default Value'):
print('call_no = {}'.format(call_no) )
print_my_arg(foo, 0, my_arg='My Value 1')
print_my_arg(foo, 1, 'My Value 2')
print_my_arg(foo, 2)
输出:
call_no = 0
my_arg = My Value 1
call_no = 1 # I'd like to see 'My Value 2' here
call_no = 2 # I'd like to see 'Default Value' here
显然人们可以自由地以上面显示的任何一种方式调用函数,这让我想知道:为什么 my_arg
不去 kwargs
呢?难道没有一种不依赖于函数调用方式的统一方式来按名称(而不是按位置)访问参数吗?
请注意:
我对print_my_args(func, call_no, my_arg)
不感兴趣,因为我说的是我事先不知道func
的签名但我想要的情况了解特定参数是否存在(按名称)。
显然这与装饰器有关,但我以更简单的方式编写了示例(或者我希望如此)。
编辑
非常感谢您对 inspect.signature 的回答。使用它,我的 print_my_arg()
的新版本是:
from inspect import signature
def print_my_arg ( func, *args, **kwargs ):
func ( *args, **kwargs )
sig = signature ( func )
if 'my_arg' not in sig.parameters: return
binding = sig.bind ( *args, **kwargs )
binding.apply_defaults ()
print ( " my_arg = {}".format ( binding.arguments [ 'my_arg' ] ) )
Isn't there a uniform way to access parameters by name (and not by
position), which doesn't depend on the way the function was invoked?
是 inspect
ing signature
:
>>> import inspect
>>> sig = inspect.signature(foo)
>>> print(sig)
(call_no, my_arg='Default Value')
>>> args = sig.bind(1, "my_value")
>>> args.arguments["my_arg"]
'my_value'
请注意,尝试将签名绑定到无效调用会引发 similar/same TypeError,在使用无效参数调用函数时会引发该错误。此外,使用默认值的参数不会出现在 args.arguments
中,除非您调用 args.apply_defaults()
另请注意,仅关键字参数将出现在 args.kwargs
字典中,而不是 args.arguments
:
import inspect
def bar(a,*, b=None):
pass
sig = inspect.signature(bar)
binding = sig.bind(1, b=5)
assert "a" in binding.arguments
assert "b" in binding.kwargs
我试图了解以下有关处理函数及其参数的内容:
def print_my_arg(func, *args, **kwargs):
func(*args, **kwargs)
if 'my_arg' in kwargs:
print(' my_arg = {}'.format(kwargs['my_arg']))
def foo(call_no, my_arg='Default Value'):
print('call_no = {}'.format(call_no) )
print_my_arg(foo, 0, my_arg='My Value 1')
print_my_arg(foo, 1, 'My Value 2')
print_my_arg(foo, 2)
输出:
call_no = 0
my_arg = My Value 1
call_no = 1 # I'd like to see 'My Value 2' here
call_no = 2 # I'd like to see 'Default Value' here
显然人们可以自由地以上面显示的任何一种方式调用函数,这让我想知道:为什么 my_arg
不去 kwargs
呢?难道没有一种不依赖于函数调用方式的统一方式来按名称(而不是按位置)访问参数吗?
请注意:
我对
print_my_args(func, call_no, my_arg)
不感兴趣,因为我说的是我事先不知道func
的签名但我想要的情况了解特定参数是否存在(按名称)。显然这与装饰器有关,但我以更简单的方式编写了示例(或者我希望如此)。
编辑
非常感谢您对 inspect.signature 的回答。使用它,我的 print_my_arg()
的新版本是:
from inspect import signature
def print_my_arg ( func, *args, **kwargs ):
func ( *args, **kwargs )
sig = signature ( func )
if 'my_arg' not in sig.parameters: return
binding = sig.bind ( *args, **kwargs )
binding.apply_defaults ()
print ( " my_arg = {}".format ( binding.arguments [ 'my_arg' ] ) )
Isn't there a uniform way to access parameters by name (and not by position), which doesn't depend on the way the function was invoked?
是 inspect
ing signature
:
>>> import inspect
>>> sig = inspect.signature(foo)
>>> print(sig)
(call_no, my_arg='Default Value')
>>> args = sig.bind(1, "my_value")
>>> args.arguments["my_arg"]
'my_value'
请注意,尝试将签名绑定到无效调用会引发 similar/same TypeError,在使用无效参数调用函数时会引发该错误。此外,使用默认值的参数不会出现在 args.arguments
中,除非您调用 args.apply_defaults()
另请注意,仅关键字参数将出现在 args.kwargs
字典中,而不是 args.arguments
:
import inspect
def bar(a,*, b=None):
pass
sig = inspect.signature(bar)
binding = sig.bind(1, b=5)
assert "a" in binding.arguments
assert "b" in binding.kwargs