1

Suppose I have a data analytics class. Each instance does some data analysis job, and output the results (the "factors") to a desginated directory as csv files. All my functions used to get results are named as get_factor_name, so I want to write a decorator that can automatically output the results of any such function to csv files. Here's my minimal example:

import pandas as pd
import functools


class DataAnalyser:
    def __init__(self):
        self.input_df = ... # some pandas df
        self.output_dir = 'some_dir/'

    def write_to_csv(self, func):
        @functools.wraps(func)
        def f(*args, **kwargs):
            # t = time.time()
            res = func(*args, **kwargs)
            if self.to_csv:
                # fac name is what follows "get_" in the func name
                fac_name = func.__name__[4:]
                res.to_csv(self.output_dir+fac_name+'.csv', )
            return res
        return f

    @write_to_csv
    def get_factor1(self):
        # do sth and get results
        df_ = ...
        return df_


data_analyser = DataAnalyser()
data_analyser.get_factor1()

However the interpreter complains that

TypeError: write_to_csv() missing 1 required positional argument: 'func'

I think the mistake may have resulted from using an instance method (i.e. one that takes an self arg inside their class) which might behave differently from a "normal" decorator. Anyway, how can I implement such a decorator that I can pass self to?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
Vim
  • 1,436
  • 2
  • 19
  • 32
  • At the time the code is run to create the class body, there are no instance methods, because there is no instance yet. The class to back the instances doesn't exist yet. They are *just (unbound) functions*. Your decorator won't be bound, there is no `self` to bind to at that stage. Whatever the decorator returns replaces what was decorated, so have *that* take a `self` argument. – Martijn Pieters May 02 '19 at 11:16
  • But the thing the decorator returns can (and should) be bindable – Mad Physicist May 02 '19 at 11:17
  • @Martijn Sorry, on mobile so didn't see your magical instantaneous dupe hammer. Apparently having a dupe hammer of my own let's me post even after you've closed the question? – Mad Physicist May 02 '19 at 11:20
  • @MadPhysicist: no, there is a grace period in which anyone with an open answer editor can still submit their answer. – Martijn Pieters May 02 '19 at 11:41
  • That sounds more reasonable than the explanation I'd concocted in my head – Mad Physicist May 02 '19 at 13:14

0 Answers0