簡體   English   中英

從關鍵字參數生成參數字典

[英]Generating a dictionary of parameters from keyword arguments

我正在嘗試生成一個字典,其中包含當前調用的非None參數的名稱和值。 這很像是應該是內置的東西,但在 Python 文檔中找不到任何能做到這一點的東西。

例如,當

def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):

   # code to generate dict of non-`None` named arguments (see below)

   ...  # other things happen later

使用參數foo(limit=5, lower_bound=100)調用,我需要以下字典: {limit=5, lower_bound=100}

有什么可以方便地為我做的嗎?


潛在的解決方案

到目前為止,我已經研究了以下內容,所有這些似乎都有缺陷:

  1. 手動制作列表(例如,如果一個參數的名稱發生了變化,它的缺點是有更多的地方可以進行更改)
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
    keys = ('limit', 'offset', 'lower_bound', 'upper_bound')
    values = (limit, offset, lower_bound, upper_bound)
    magic_dict = {k: v for k, v in zip(keys, values) if v is not None}
  1. locals()鏈接— 這將需要刪除不應該進入字典的所有內容(即值為None的鍵)。 如果在魔法字典代碼上方添加變量定義,這似乎也容易出錯,這也需要刪除。
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
    magic_dict = {k: v for k, v in locals().items() if v is not None}
  1. inspect - 鏈接- signaturebind ,這仍然需要參數列表
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
    sig = signature(foo)
    sig_args = sig.bind(limit, offset, lower_bound, upper_bound).arguments
    magic_dict = {k: v for k, v in sig_args.items() if v is not None}

其他想法包括創建一個類以使getattr可用

感覺就像我遺漏了一些明顯的東西——我們將不勝感激!


有人建議從參數中選擇所有非None元素並將它們放入python字典中的優雅方法是什么? ,其響應主要是“移至**kwargs ”。 我最初的反應是,我更願意保留一份具體的論據清單——我的邏輯是不是很糟糕? Python 的典型最佳實踐是什么?

您可以嘗試使用裝飾器:

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

現在您可以致電:

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

你也可以使用 locals 方法,但是在你的函數頂部復制 locals。 最后,可以使用原始本地人的鍵並僅選擇返回語句中的鍵:

def foo(a=None, b=None, c=None):
    original_locals = locals().copy()
    d = 'test' #Test adding new variable which should not be returned
    return {k:v for k,v in locals().items() if k in original_locals.keys() and v is not None}

foo(1)
>> {'a': 1}
foo(1, 2, 3)
>> {'a': 11, 'b': 2, 'c': 3}

請注意,您必須復制本地人,否則此方法將不起作用

如果您還想添加kwargs

def func(a=None, b=None, c=None, **kwargs):
    org_loc = locals().copy()
    def check_kwargs(d):
        if 'kwargs' in d.keys():
            d.update(d['kwargs'])
            del d['kwargs']
    check_kwargs(org_loc)
    d = 'test'
    new_loc = locals()
    check_kwargs(new_loc)
    return {k:v for k,v in new_loc.items() if k in org_loc.keys() and v is not None}

然后:

func(1)
>> {'a':1}
func(1, test='test')
>> {'a': 1, 'test': 'test'}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM