簡體   English   中英

使用裝飾器提供新的 args、kwargs

[英]Using decorators to supply new args, kwargs

我做了一些關於裝飾器的研究,主要是關於典型的用例。 事實證明,在大多數情況下,它們充當驗證器、計時器、權限檢查器——非常透明的東西。 我想知道使用它們來預先計算並向裝飾函數提供一些變量是否會是 Pythonic。

我腦子里的情況是這樣的:

裝飾器:

def foo(fn):
    @functools.wraps(fn)
    def wrapper(*args, **kwargs):
        fn_name = fn.__name__
        var = Test._do_something(Test.store_dict[fn_name])
        kw_args = {**kwargs, **dict(var=var)}
        return fn(*args, **kw_args)
    return wrapper

班級:

class Test:
    store_dict = dict(fn1='fn1_operator',
                      fn2='fn2_operator')

    @staticmethod
    @foo
    def fn1(dummy_data, **kwargs):
        return Test.__handle_data(dummy_data=dummy_data,
                                  **kwargs)
    @staticmethod
    @foo
    def fn2(dummy_data, **kwargs):
        return Test.__handle_data(dummy_data=dummy_data,
                                  **kwargs)

    @staticmethod
    def _do_something(var):
        return var

    @staticmethod
    def __handle_data(dummy_data, var):
        return (dummy_data, var)

用法:

test_instance = Test()
test_instance.fn1(dummy_data='test')

正如您所看到的, fn1fn2方法在做幾乎相同的事情(調用__handle_data方法),但具有不同的var 變量var取決於被調用的函數名。 使用var=fn1_operator等調用fn1結果。 在我心中有 Python 之禪:

簡單勝於復雜。

我懷疑那是pythonic。

另一方面,如果沒有那個裝飾器,我的代碼會有很多重復:

@staticmethod
def fn1(dummy_data):
    var = _do_something('fn1')
    return Test.__handle_data(dummy_data=dummy_data,
                              var=var)
@staticmethod
def fn2(dummy_data):
    var = _do_something('fn2')
    return Test.__handle_data(dummy_data=dummy_data,
                              var=var)

這是正確的嗎? 我應該改變什么?

我不會在這里使用裝飾器; 我會寫一個函數來返回特定數據的閉包。

def make_test(arg):
    @staticmethod
    def _(dummy_data):
        var = _do_something(arg)
        return Test.__handle_data(dummy_data, var=var)
    return _

fn1 = make_test('fn1')
fn2 = make_test('fn2')

(我沒有測試,但我很確定如果你裝飾閉包,或者簡單地返回一個未裝飾的函數並編寫fn1 = staticmethod(make_test('fn1'))等,它的工作原理是一樣的。)


使用專注於常見內容的裝飾器,它可能看起來像

def foo(f):
    def _(dummy_data):
        var = _do_something(f())
        return Test.__handle_data(dummy_data, var=var)
    return _

@foo
def fn1(self):
    return 'fn1'


@foo
def fn2(self):
    return 'fn2'

它具有相同的行為,但意圖不太清楚。 裝飾器中隱藏了太多東西。

暫無
暫無

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

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