【问题标题】:mapping arguments passed to function to local namespace using **kwargs?使用 **kwargs 将传递给函数的参数映射到本地命名空间?
【发布时间】: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))

【问题讨论】:

  • 你为什么要使用kwargskwargs 适用于当您知道您感兴趣的参数名称时。\
  • 弄清楚它的作用以及我为什么要使用它。我主要是在寻找一种将变量字典传递给函数的快速方法
  • 你不需要用kwargs 定义你的函数来做到这一点。您可以直接使用def foo(apple, zoom, bar): ... 并将其称为foo(**your_dict)
  • 或者,当然,您可以将 dict 作为常规参数并以通常的方式索引 dict。
  • 这就是我现在要做的。我创建了一个带有很多参数的函数,并且厌倦了每次定义变量,并且很好奇 **kwargs 是否是答案,但我了解到没有捷径可走。无论哪种方式,我都必须将变量“初始化”到函数的命名空间。

标签: python function namespaces arguments keyword-argument


【解决方案1】:

kwargs 是一个字典,所以你可以简单地通过它们的键来引用其中的值:

def test(**kwargs):
    if kwargs:
        print(f'apple: {kwargs.get("apple")}')
        print(f'zoom:  {kwargs.get("zoom")}')
        print(f'bar: {kwargs.get("bar")}')

【讨论】:

  • 我会说这是 OP 用例的最佳答案
猜你喜欢
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
相关资源
最近更新 更多