Python 3 - 如何 'convert' 一个以字典为参数的函数转换为以关键字参数为参数的函数?

Python 3 - How to 'convert' a function taking a dict as arguments to one which takes keyword arguments?

我有一个函数 g() 以字典作为参数,例如:

>> g({'a':'foo', 'b':'bar', 'c','baz'})
a = foo
b = bar
c = baz

我想 'convert' g() 或从 g() 创建一个新函数 f() 这样它将采用位置参数而不是字典,例如:

>> f(a='foo', b='bar', c='baz')
a = foo
b = bar
c = baz

背景:

或者谁能想到更好的方法来解决这个问题?

谢谢!

本质上,你想要的是一个函数装饰器,它在调用你的函数之前执行某种预处理逻辑。首先,创建你的装饰器。它将接收关键字参数并将其传递给内部函数。

In [239]: def baz(fnc):
     ...:     def inner(**kwargs):
     ...:         fnc(kwargs)
     ...:     return inner
     ...: 

使用 @...:

用装饰器语法装饰你的原始函数
In [240]: @baz
     ...: def foo(dict_):
     ...:     for k in dict_:
     ...:         print(k, '=', dict_[k])
     ...:         

调用您的原始函数:

In [241]: foo(a=1, b=2, c=3)

a = 1
b = 2
c = 3

我会使用 exec 方法,因为它允许您做任何您可以在代码中做的事情,所以没有太多额外的东西需要学习。例如,如果将以下代码插入代码中,您可以创建一个简单的函数,该函数对字典中的每个索引都有一个参数,参数标识符是字母表中的每个小写字母(因此只有在您不这样做时才有效) '超过 26 个参数

def MakeFunction(DictionaryToUse):
    arguments = ""#Defaults to no arguments
    for i in range(97,97+len(DictionaryToUse)):#Adds another argument per dictionary item
        arguments += chr(i) + ","
    if len(arguments) > 0:
        arguments = arguments[:-1]#Removes the last comma, if there is one
    exec("def f(" + arguments + """):
    print("hi")""",globals())#Defines a new function f so it can be called as a global function.

因此,例如,要创建一个具有 3 个参数的函数,您可以使用:

MakeFunction({"foo":0,"bar":10,"foobar":96})

然后可以调用名为 f 的新函数,带有 3 个参数。

f(1,2,3)

您显然必须根据自己的需要对其进行调整,将 f 替换为您想要的函数名称,并添加您希望函数执行的任何操作,而不是 print("hi")

我找到了解决问题的简单方法

这是一个简单的函数 g 以字典作为我想要的参数 'convert':

>>> def g(my_dict):
        print('a:', str(my_dict['a']))
        print('b:', str(my_dict['b']))

一个接受关键字参数的新函数 f 可以很容易地从 g:

创建
>>> def f(**kwargs):
        return g(kwargs)

让我们尝试 f 使用关键字参数:

>>> f(a='foo', b='bar')
a: foo
b: bar

f 不适用于位置参数:

>>> f('foo', 'bar')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-619-505f263ccdf6> in <module>()
----> 1 f(1, 2)

TypeError: f() takes 0 positional arguments but 2 were given

备注:

  1. 我最初要求 'converted' 函数 f 接受 位置参数 。在做了更多研究之后,我发现我的意思是 关键字参数 。我在问题中使用了错误的术语,我很抱歉。
  2. 我对@COLDSPEED 提出的装饰器的尝试只取得了部分成功:我能够创建一个函数 f,它似乎可以工作,但不知何故,其余代码看到它返回的值是 None。如果您有任何解释,请随时发表评论。