从关键字参数生成参数字典

use*_*023 7 python function parameter-passing

我正在尝试生成一个包含非None参数当前调用的名称和值的字典。这非常感觉应该是内置的,但在 Python 文档中找不到任何能完全做到这一点的东西。

\n

例如,当

\n
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):\n\n   # code to generate dict of non-`None` named arguments (see below)\n\n   ...  # other things happen later\n
Run Code Online (Sandbox Code Playgroud)\n

使用参数调用foo(limit=5, lower_bound=100),我需要以下字典:{limit=5, lower_bound=100}。

\n

有什么东西可以方便地为我做到这一点吗?

\n
\n

潜在的解决方案

\n

到目前为止,我已经研究了以下内容,所有这些似乎都有缺陷:

\n
    \n
  1. 手动创建列表(它的缺点是有更多地方可以进行更改,例如,参数名称已更改)
  2. \n
\n
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):\n    keys = (\'limit\', \'offset\', \'lower_bound\', \'upper_bound\')\n    values = (limit, offset, lower_bound, upper_bound)\n    magic_dict = {k: v for k, v in zip(keys, values) if v is not None}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. locals()\xe2\x80\x94链接\xe2\x80\x94 需要删除所有不应该进入字典的内容(即值为 的键None)。如果变量定义添加到魔法字典代码之上,这似乎也容易出错,这也需要删除。
  2. \n
\n
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):\n    magic_dict = {k: v for k, v in locals().items() if v is not None}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. inspect\'s \xe2\x80\x94链接\xe2\x80\x94signature和bind,仍然需要参数列表
  2. \n
\n
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):\n    sig = signature(foo)\n    sig_args = sig.bind(limit, offset, lower_bound, upper_bound).arguments\n    magic_dict = {k: v for k, v in sig_args.items() if v is not None}\n\n
Run Code Online (Sandbox Code Playgroud)\n

其他想法包括开设一个课程以getattr提供

\n

感觉就像我错过了一些明显的 \xe2\x80\x94\xc2\xa0feedback 将不胜感激!

\n
\n

有人建议\n从参数中选择所有非 None 元素并将它们放入 python 字典中的优雅方法是什么?,其回答主要是“移至**kwargs”。我最初的反应是我更愿意保留一个特定的参数列表 \xe2\x80\x94 这是我的逻辑不好吗?Python 的典型最佳实践是什么?

\n

Cyt*_*rak 5

您可以尝试使用装饰器:

def capture(func):
    capture.kwds = None
    def wrap(*args, **kwargs):
        capture.kwds = kwargs
        return func(*args, **kwargs)
    return wrap
    
@capture
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
    return None
Run Code Online (Sandbox Code Playgroud)

现在您可以致电:

>>> foo(limit=1, offset=2, lower_bound=3, upper_bound=4)
None
>>> capture.kwds
{'limit': 1, 'offset': 2, 'lower_bound': 3, 'upper_bound': 4}
Run Code Online (Sandbox Code Playgroud)

  • 您不认为在 kwargs 捕获之后还应该在 ``wrap``` 函数中调用 ``func``` 吗? (2认同)