Python 3 - 如何转换'一个函数将一个dict作为一个带有关键字参数的函数的参数?

时间:2017-08-18 18:51:45

标签: python-3.x function dictionary arguments keyword-argument

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

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

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

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

背景:

  • 我的目标是编写一个小API,使用户可以轻松利用此核心包:https://github.com/fmfn/BayesianOptimization
  • 要使用API​​,用户必须提供用户定义的功能。
  • 我未来的API将为核心包提供用户定义的功能。
  • 核心包需要使用位置参数(不是dict)的函数。
  • 这些用户定义的函数可能很复杂,并且很可能需要很多参数,我宁愿告诉用户构建他们的函数,将字典作为参数而不是一长串的位置参数(并在其中进行某种转换)我的API在调用核心包之前。)

或者有人能想出更好的解决方法吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

我会使用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})

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

f(1,2,3)

你必须明确地定制它以满足你的需要,用你想要的功能名称替换f,并添加你想要的功能而不是print("hi")

答案 2 :(得分:0)

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

这是一个简单的函数g将dict作为我想要'转换'的参数:

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

可以从f轻松创建一个带有关键字参数的新函数g

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

让我们使用关键字args尝试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. 我最初要求'转换'函数f采用位置参数。在做了额外的研究后,我发现我的意思是关键字参数。我在问题中使用了错误的术语,道歉。
  2. 我对@COLDSPEED提议的装饰器的尝试只取得了部分成功:我能够创建一个似乎有效的函数f,但不知怎的,其余的代码看到它返回的值{{1 }}。如果您有解释,请随时发表评论。