【发布时间】:2019-05-01 22:27:41
【问题描述】:
如果这是一个重复的问题,我提前道歉.. 我想更好地理解 **kwargs 在 python 中的东西,并且实际上希望能够编写一个可以处理解包和内部引用 @987654321 的函数@pairs 传入 **kwargs 参数。
我的小例子如下:
arguments = {'apple': 50, 'zoom': 'foo', 'bar': True}
我希望能够引用传递给函数的字典的键和值,而无需从函数本身中显式引用它们。
def test(**kwargs):
if kwargs is not None:
print(f'apple: {apple}')
print(f'zoom: {zoom}')
print(f'bar: {bar}')
通过test(**arguments) 调用上述方法当然会失败,但是有没有办法将 **kwargs “解包”到函数内的本地命名空间中以完成我的想法?
我考虑过的一件事是在函数中创建一个字典,然后使用exec() 将键:值对编译到这个命名空间字典中,但这似乎有点麻烦。
还有另一种方法可以将局部变量从 **kwargs 直接分配给函数吗?
提前致谢。
编辑
我还使用vars() 进行了探索,并编写了以下内容:
def test(**kwargs):
try:
print(**vars())
except Exception as e:
print(e, '\n\n')
print(vars())
if kwargs is not None:
try:
print(f'apple: {apple}')
print(f'zoom: {zoom}')
print(f'bar: {bar}')
except:
for k, v in kwargs.items():
print(f'k: {k} : v: {v}')
输出如下:
'kwargs' is an invalid keyword argument for this function
{'kwargs': {'apple': 50, 'zoom': 'foo', 'bar': True}, 'e':TypeError("'kwargs' is an invalid keyword argument for this function",)}
k: apple : v: 50
k: zoom : v: foo
k: bar : v: True
我注意到print(**kwargs) 正在尝试将“kwargs”作为命名变量进行访问。我想我要解决的问题是,如果使用默认参数定义函数,那么传入 **kwargs 会解决问题吗?我可以试试这个,看看它是否有效并更新..
编辑二
这行得通..看起来定义函数具有命名默认值允许我直接从 **kwargs 引用这些变量,而不这样做需要引用 **kwargs 字典并无论如何都知道键。
arguments = {'apple': 50, 'zoom': 'foo', 'bar': True, 'baz': 99}
def test(apple = None, zoom = 'fee', bar = False, **kwargs):
if kwargs is not None:
try:
print(f'apple: {apple}')
print(f'zoom: {zoom}')
print(f'bar: {bar}')
except Exception as e:
print(e, '\n\n\n')
for k, v in kwargs.items():
print(f'k: {k} : v: {v}')
test(**arguments)
编辑 III: 更新
以下内容最接近我最初尝试传达和实施的内容。处理任意用户关键字参数的函数和 将它们绑定到本地命名空间中的变量...
def test(**kwargs):
ns = {}
args_string = ''
for k, v in kwargs.items():
print(f'k: {k}, v: {v}')
try:
args_string += str(k) + '=' + '{}'.format(int(v))+'\n'
except:
args_string += str(k) + '=' + '"{}"'.format(str(v))+'\n'
exec(args_string, ns)
return {k:v for k, v in ns.items() if k in kwargs.keys() }
运行以下允许我访问变量,但我怀疑这不是安全或“好”的代码。
locals().update(test(**arguments))
【问题讨论】:
-
你为什么要使用
kwargs?kwargs适用于当您不知道您感兴趣的参数名称时。\ -
弄清楚它的作用以及我为什么要使用它。我主要是在寻找一种将变量字典传递给函数的快速方法
-
你不需要用
kwargs定义你的函数来做到这一点。您可以直接使用def foo(apple, zoom, bar): ...并将其称为foo(**your_dict)。 -
或者,当然,您可以将 dict 作为常规参数并以通常的方式索引 dict。
-
这就是我现在要做的。我创建了一个带有很多参数的函数,并且厌倦了每次定义变量,并且很好奇 **kwargs 是否是答案,但我了解到没有捷径可走。无论哪种方式,我都必须将变量“初始化”到函数的命名空间。
标签: python function namespaces arguments keyword-argument