1

I'd like to know what's the best way to organize a class in Python as checking on previous questions here I didn't find exactly what I needed. Let's say I have this class:

class A():
    def __init__(self):
        self.data = #A pandas dataframe I get from an online API

I have then many functions inside this class which I'd like to organize. All these functions will need the Dataframe contained in self.data as parameter.

I thought to create a subclass for every group of functions but I didn't find a way to then refer to self.data from inside the subclass.

I found then online that I could organize the functions in different modules. However how to I pass the Dataframe in self.data as parameter to the functions? Let's say function1 is defined as following:

def function1(self):
    print (self.data)

If the function was defined inside the class, I could do this:

x = A()
x.function1()

and get the print without passing self.data as parameter. How would I do this if a function is defined in another module and I import it in the main class without passing self.data as parameter every time? Thanks in advance.

EDIT: If I do:

class A():
    def __init__(self):
        self.x = 1
        self.b = self.B()

    class B(A):
        def print(self):
            print(self.x)

I get an error saying "A is not defined"

Lorenzo
  • 111
  • 3
  • 10
  • You could check this [SO thread](https://stackoverflow.com/questions/533631/what-is-a-mixin-and-why-are-they-useful) for ideas... – Léopold Houdin Dec 10 '19 at 19:26
  • 1
    Check this site, a great resource for organizing your python code: https://docs.python-guide.org/writing/structure/ – smishra Dec 10 '19 at 19:27
  • 1
    maybe better don't put data in class but use it as argument - `def function1(self, data):` – furas Dec 10 '19 at 19:38
  • you should put data when you create instance - `x = A(data)` and `def __init__(self, data): self.data = data`. And then you don't have problem to use class from other module, and everyone will see what data are used in class. – furas Dec 10 '19 at 19:40
  • "I thought to create a subclass for every group of functions but I didn't find a way to then refer to self.data from inside the subclass." What exactly do you mean by subclass here? Can you please elaborate? – juanpa.arrivillaga Dec 10 '19 at 20:19
  • @juanpa.arrivillaga I mean that if I define class A as class A(): then a subclass B would be like: class B(A): – Lorenzo Dec 10 '19 at 20:38
  • OK, then if you are properly subclassing things, then you should be able to simply use `self.data`. You should provide a [mcve] – juanpa.arrivillaga Dec 10 '19 at 20:39
  • @juanpa.arrivillaga see my edit – Lorenzo Dec 10 '19 at 20:48
  • 1
    Right, why are you *nesting* the class definition of `B` inside the body of `A`? Don't do that, just move it outside. – juanpa.arrivillaga Dec 10 '19 at 20:52
  • @juanpa.arrivillaga I nest the class because loading the data in self.data = ... is heavy. So if I have everything inside the class A I would load the data once and use it with every function while if I declare a subclass outside A, I would need to load the data when I call a function inside A and when I call a function inside B. Correct me if I'm wrong on this. – Lorenzo Dec 10 '19 at 21:20
  • 1
    @Lorenzo yes, you are wrong. I don't know why you think that but it isn't true. Nesting the class only affects the namespace, which is why you are getting an error. Don't nest classes, there is almost never a good reason to in Python – juanpa.arrivillaga Dec 10 '19 at 21:21
  • @juanpa.arrivillaga ah ok, thank you. I wans't sure on this point. I tried your solution and seem to work fine! Thank you very much! – Lorenzo Dec 10 '19 at 21:42

1 Answers1

1

I like your approach to create subclasses for each group of methods. First start with a base class which stores your data

class DataBase:
    def __init__(self, data):
        self._data = data

Then write your different groups of methods ...

class GroupB(DataBase):
    def func_b1(self):
        return self._data

    def func_b2(self):
        return self._data

class GroupA(DataBase):
    def func_a1(self):
        return self._data

    def func_a2(self):
        return self._data

... and finally collect all these groups together

class MyData(GroupA, GroupB):
    pass


>>> d = MyData(123)
>>> d.func_a1()
123
>>> d.func_b2()
123

I hope this helps you.

fhgd
  • 402
  • 2
  • 10