2

I'm having a Tweetanalyzer class, having a dataframe as an instancevariable.

Now I want to create a write_to_csv function which can take all parameters of the pandas to_csv function.

The reason Im doing it is I dont want to call -> Tweetanalyzer.df.to_csv just Tweetanalyzerobject.write_to_csv but with the same functionality as to_csv.

I guess wrapping the function could be the right way including *args and **kwargs but I'm not getting it to work.

class TweetAnalyzer:

    def __init__(self, tweets, df = pd.DataFrame({'A' : []})):

        self.tweets = tweets
        if df.empty:
            self.df = self.tweets_to_dataframe(self.tweets)
        else:
            self.df = df

    def write_to_csv(self):

        self.df.to_csv()

So if i call object.write_to_csv(encoding = "utf-8"), it will be parsed into the to_csv code and the code will work without specifying "encoding" in my function write_to_csv.

Thank you!!!

C.Nivs
  • 12,353
  • 2
  • 19
  • 44
Dustin
  • 63
  • 1
  • 4
  • 2
    I would avoid using `pd.DataFrame()` as a default arg, just in case it gets modified. Use `df = None` as the default and you can use `self.df = df if df is not None else pd.DataFrame...` – C.Nivs Jun 19 '19 at 17:46
  • Oh, thank you! I Tried it with df = None before but checked for df == None and if I called it with a dataframe the interpreter told me: ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). Now it works :) – Dustin Jun 19 '19 at 17:54
  • It does feel weird to have that as a default arg. What do you mean "just in case it gets modified" tho? – Dustin Michels Jun 19 '19 at 18:11
  • @DustinMichels if you were to do, say `df.append(row)` on the default arg, that's an in-place operation that will be reflected on any other instance of the class, because default args are compiled once – C.Nivs Jun 19 '19 at 19:00
  • @DustinMichels this is a bit easier to see if you try something like `def a(x=[]): x.append(1); print(x)` and call it twice, you'll see `x` become `[1]`, then `[1,1]` – C.Nivs Jun 19 '19 at 19:03
  • Ah I totally see the problem. Really interesting. Thanks. – Dustin Michels Jun 19 '19 at 19:06

1 Answers1

2

Yup, using *args and **kwargs is probably the right idea! Something like this:

class TweetAnalyzer:
    def __init__(self, tweets, df=pd.DataFrame({"A": []})):
        self.tweets = tweets
        if df.empty:
            self.df = self.tweets_to_dataframe(self.tweets)
        else:
            self.df = df

    def write_to_csv(self, *args, **kwargs):
        self.df.to_csv(*args, **kwargs)

For a fuller explanation, see: What does ** (double star/asterisk) and * (star/asterisk) do for parameters?

Dustin Michels
  • 2,951
  • 2
  • 19
  • 31