簡體   English   中英

帶有在運行時傳遞的參數的裝飾器

[英]Decorator with parameters passed at runtime

關於在python中使用帶有或不帶有參數的裝飾器,存在很多問題,但我的情況有些不同。

一般問題

我需要的是一個裝飾器,該裝飾器除了函數本身(以及args和kwargs函數)之外還接受一些參數。 但是,這些參數是在聲明裝飾函數之后計算的。

我的具體情況

我編寫了許多處理pd.DataFrame的函數以進行機器學習,它們獲取DF作為輸入,並返回DF作為輸出。 在許多情況下,我不想將它們稱為一個DF,而是將多個訓練和測試集串聯在一起。 這樣做的動機是我討厭重復代碼,而替代方法是每個步驟調用兩次(每組一次)。 預處理功能的作者也不必擔心用戶經常一次要使用2套這樣的事實。

當前代碼如下所示:

def train_and_test(preprocess):
  def preprocess_wrapper(**kwargs):
    def concat(train, test):
        train['is_train'] = True
        test['is_train'] = False
        return pd.concat([train, test])

    def split(full):
        train = full[full['is_train']]
        test = full[~full['is_train']]
        train = train.drop('is_train', axis=1)
        test = test.drop('is_train', axis=1)
        assert len(full) == (len(train) + len(test))
        return train, test

    train = kwargs['train']
    test = kwargs['test']
    full = concat(train, test)
    processed = preprocess(full)
    return split(processed)

return preprocess_wrapper

@train_and_test # I would like to pass train and test as arguments here but these are loaded by client code
def my_preprocessor(df):
  preprocessed = do_something_smart(df)
  return preprocessed

我想要的是

我希望此代碼的客戶能夠通過將火車和測試集傳遞給裝飾器來調用在一個DF上定義的函數。 像這樣:

train, test = pd.read_csv('data/train.csv'), pd.read_csv('data/test.csv')

train, test = preprocess(train, test) # In reality preprocess signature expects one DF but user can now treat it like it accepted 2

我們需要更深入!

裝飾器只是在一個函數上運行的一個函數。

那么,為什么不編寫一個返回對函數進行操作的函數的函數呢?

def paramizer(*args):
    def normal_decorator(f):
        ...stuff that uses the decorator args to customize behavior...
        def wrapper():
            ...stuff decorating f...
            return f()
        return wrapper
    return normal_decorator

@paramizer(arg1, arg2) #=> returns a customized decorator and applies it to function
def function()

暫無
暫無

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

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