【问题标题】:Decorator with parameters passed at runtime带有在运行时传递的参数的装饰器
【发布时间】: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

【问题讨论】:

  • 不是很清楚,你必须以某种方式将测试和训练数据集传递给函数,但它没有得到这些参数。
  • 您能否编写完整的未装饰管道,以便我们更好地了解您想要什么以及是否可以装饰它?

标签: python decorator


【解决方案1】:

我们需要更深入!

装饰器只是对函数进行操作的函数。

那么,为什么不写一个函数来返回对函数进行操作的函数呢?

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

【讨论】:

  • arg1 和 arg2 仅在运行时已知。这不起作用(除非在运行时显式装饰f = paramizer(train, test)(myfunc))。
猜你喜欢
  • 1970-01-01
  • 2018-02-06
  • 2020-03-22
  • 1970-01-01
  • 2012-06-13
  • 2021-07-27
  • 2014-07-21
  • 1970-01-01
  • 2018-05-30
相关资源
最近更新 更多