使用Python中的字典为函数提供默认参数

Sta*_*ean 14 python

假设我有一个字典:

d = {'a': 3, 'b':4}
Run Code Online (Sandbox Code Playgroud)

我想创建一个函数f,该函数执行的功能与此函数完全相同:

def f(x, a=d['a'], b=d['b']):
  print(x, a, b)
Run Code Online (Sandbox Code Playgroud)

(不一定要打印,但是可以对变量进行一些操作并直接从其名称中调用)。

但是我想直接从字典创建此函数,也就是说,我想拥有一个看起来像的东西

def f(x, **d=d):
  print(x, a, b)
Run Code Online (Sandbox Code Playgroud)

并且其行为类似于先前定义的功能。我的想法是,我有一个很大的字典,其中包含函数参数的默认值,并且我不想这样做

def f(a= d['a'], b = d['b'] ...)
Run Code Online (Sandbox Code Playgroud)

我不知道在python中是否有可能。任何见识表示赞赏!

编辑:想法是能够打电话f(5, a=3)。Edit2:问题不在于将字典中存储的参数传递给函数,而是要定义一个函数,其参数名称和默认值存储在字典中。

Oli*_*çon 7

无法在函数定义中实现此目标,因为Python静态确定函数的范围。虽然,可以编写一个装饰器以添加默认的关键字参数。

from functools import wraps

def kwargs_decorator(dict_kwargs):
    def wrapper(f):
        @wraps(f)
        def inner_wrapper(*args, **kwargs):
            new_kwargs = {**dict_kwargs, **kwargs}
            return f(*args, **new_kwargs)
        return inner_wrapper
    return wrapper
Run Code Online (Sandbox Code Playgroud)

用法

@kwargs_decorator({'bar': 1})
def foo(**kwargs):
    print(kwargs['bar'])

foo() # prints 1
Run Code Online (Sandbox Code Playgroud)

或者,如果您知道变量名称,但不知道其默认值,则...

@kwargs_decorator({'bar': 1})
def foo(bar):
    print(bar)

foo() # prints 1
Run Code Online (Sandbox Code Playgroud)

警告

例如,上面的代码可用于动态生成具有不同默认参数的多个函数。虽然,如果要传递的参数对于每个函数都相同,则简单地传递dict参数a会更简单,更惯用。

  • 所以您想设置一个参数?不夸张吗?我认为这是不可能的,因为本地作用域是在函数定义中构建的 (2认同)

ben*_*nrg 4

Python 的设计使得任何函数的局部变量都可以通过查看函数的源代码来明确确定。所以你建议的语法

def f(x, **d=d):
  print(x, a, b)
Run Code Online (Sandbox Code Playgroud)

是不可能的,因为没有任何东西表明 和a是否是b本地的;f它取决于字典的运行时值,其值可能会在运行过程中发生变化。

如果您可以明确列出所有参数的名称,则可以在运行时自动设置它们的默认;其他答案已经很好地涵盖了这一点。无论如何,列出参数名称可能是很好的文档。

如果您确实想在运行时从 的内容合成整个参数列表d,则必须构建函数定义的字符串表示形式并将其传递给execcollections.namedtuple例如,这就是工作原理。

模块和类范围中的变量是动态查找的,因此这在技术上是有效的:

def f(x, **kwargs):
    class C:
        vars().update(kwargs)  # don't do this, please
        print(x, a, b)
Run Code Online (Sandbox Code Playgroud)

但除IOPCC条目外,请不要这样做。