【发布时间】:2018-04-23 21:34:02
【问题描述】:
在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
【问题讨论】:
-
不是很清楚,你必须以某种方式将测试和训练数据集传递给函数,但它没有得到这些参数。
-
您能否编写完整的未装饰管道,以便我们更好地了解您想要什么以及是否可以装饰它?