Huy Nguyen
Huy Nguyen

Reputation: 73

building a class from an existing one

I am trying to build a class from pandas DataFrame. I just want to add an attribute 'name' to DataFrame class. But the codes below yield errors in recursion maximum depth reached. Which way to make it work? Thanks

import pandas as pd
class DatFrame(pd.DataFrame):
    def __init__(self, name, data=None, index=None, columns=None,
                 dtype=None, copy=False):
        self.name = name
        pd.DataFrame.__init__(self, data=None, index=None, 
                              columns=None, dtype=None, copy=False)


x = array([[9, 7, 5],
          [7, 3, 1],
          [8, 8, 3],
          [7, 4, 3]])
cols = ['a', 'b', 'c']
index = ['D', 'E', 'F', 'G']

s = DatFrame('huy', x, index, cols)

Error: RecursionError: maximum recursion depth exceeded while calling a Python object

Upvotes: 4

Views: 474

Answers (1)

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

First, you're passing None to all parameters of your dataframe

Second, the fix it is to call the __init__ method first, before setting name.

It's probably because the pd.DataFrame object expects an empty variable dictionary when initializing (recursion occurs in __getattr__), and your name member confuses it:

class DatFrame(pd.DataFrame):
    def __init__(self, name, data=None, index=None, columns=None,
                 dtype=None, copy=False):
        pd.DataFrame.__init__(self, data=data, index=index,
                              columns=columns, dtype=dtype, copy=copy)
        self.name = name

As a general rule, it's always better to call the parent constructor first thing, then set your specifics.

As comments said, if it's only to add name (without adding methods) you could create a factory method that adds dynamically the attribute, no need to inherit:

def create_datframe(name,*args,**kwargs):
    r = pd.DataFrame(*args,**kwargs)
    r.name = name
    return r

Upvotes: 5

Related Questions