2017-11-10 6 views
1

pythonでパラメータの有無にかかわらずデコレータの使用に関する多くの質問がありますが、私の場合は少し異なります。実行時にパラメータが渡されるデコレータ

一般的な質問

私は必要なものの機能自体のほかに、いくつかのパラメータを受け取りデコレータである(これは引数とkwargsからの機能)。しかし、これらのパラメータは、装飾された関数が宣言された後に計算されます。私は機械学習のためのpd.DataFrameを処理する関数の数を書かれている

私の特定のケース

、彼らは、入力としてDFを取得し、出力としてDFを返します。多くの場合、1つのDFではなく、複数のトレーニングセットとテストセットを連結して呼び出す必要があります。その動機は、私はコードの重複が嫌いで、代替案はすべてのステップを2回呼び出すことです(各セットごとに1回)。また、前処理機能の作成者は、ユーザーが一度に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 

私は

たい私は、このコードのクライアントは、列車を渡すことで 1 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 
+0

テストとトレーニングのデータセットを何らかの形で関数に渡す必要がありますが、これらのパラメータは取得されません。 –

+0

完全装飾パイプラインを書いて、あなたが望むものをより良く知ることができ、それを飾ることが可能ですか? –

答えて

0

もっと深く進む必要があります。

デコレータは、関数上で動作する単なる関数です。

さて、関数で動作する関数を返す関数を書かないのはなぜですか?

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() 
+0

'arg1'と' arg2'は実行時にのみ認識されます。これはうまく動作しません(明示的に 'f = paramizer(train、test)(myfunc)')。 –

関連する問題