簡體   English   中英

Python裝飾器查找鍵存在,並將其作為參數傳遞

[英]Python decorator to find key exist, and pass it as argument

我想知道是否可以使用裝飾器查看函數的輸入是否為:

  1. 一個字典,如果沒有字典則運行該方法
  2. 如果它是字典,則從中提取指定的鍵,並將其傳遞給方法

例:

@get_values(['username', 'password'])
    def log_me_in(username, password)
       # login logic
       if username == password:
           return True
       return False

調用方式:

log_me_in(username = 10, password = 10)
>>>> True
log_me_in(10, 10)
>>>> True
log_me_in({'username': 10, 'password': 10})
>>>> True
log_me_in({'username': 10, 'password': 10, 'something': 10})
>>>> True
log_me_in({'username': 10, 'something': 10})
>>>> EXCEPTION
log_me_in({})
>>>> EXCEPTION
log_me_in([])
>>>> EXCEPTION

如果要將值作為位置參數傳遞(根據傳遞給裝飾器的params列表中的位置):

def getvalues(params):
    getter = itemgetter(*params)
    def deco(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            if len(args) == 1 and not kwargs and isinstance(args[0], Mapping):
                return func(*getter(args[0]))
            else:
                return func(*args, **kwargs)
        return wrapper
    return deco

如果您想將它們作為關鍵字參數傳遞:

def getvalues(params):
    def deco(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            if len(args) == 1 and not kwargs and isinstance(args[0], Mapping):
                return func(**{key: value for key, value in args[0].items() 
                               if key in params})
            else:
                return func(*args, **kwargs)
        return wrapper
    return deco

我必須發明自己的規則來填補規范中的所有空白,但我認為它們有些合理。

而且,正如我在評論中提到的那樣,我認為如果getvalues將其參數名稱作為單獨的參數而不是列表來使用,將會更加友好。 要解決此問題,只需將第一行更改為def getvalues(*params):

有可能,是的。 但是有必要嗎? 通過使用**傳遞關鍵字參數,可以得到類似的結果:

>>> log_me_in(**{'username': 10, 'password': 10})
True

一個區別是不允許傳遞something Python錯誤出現在無法識別的關鍵字參數上。 看到:

>>> log_me_in(username=10, password=10)
True
>>> log_me_in(10, 10)
True
>>> log_me_in(**{'username': 10, 'password': 10})
True
>>> log_me_in(**{'username': 10, 'password': 10, 'something': 10})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: log_me_in() got an unexpected keyword argument 'something'
>>> log_me_in(**{'username': 10, 'something': 10})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: log_me_in() got an unexpected keyword argument 'something'
>>> log_me_in(**{})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: log_me_in() missing 2 required positional arguments: 'username' and 'password'
>>> log_me_in(*[])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: log_me_in() missing 2 required positional arguments: 'username' and 'password'

暫無
暫無

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

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