Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a class inherit methods (or subclass) from a different file? Is this "Pythonic"?

In trying to build a scientific Python package, I'm aiming to separate key functionality into different .py files for clarity. Specifically, it seems logical to me to split complicated numerical calculations for a model into one python file (say, "processing.py"),and plotting routines for their visualisation into another python file ("plotting.py").

For convenient and memory-efficient usage, the model class should be able to inherit all the plotting methods, making them easily accessible for the user, yet keeping the code easy to maintain and read by separating scientific numerical code from visualisation code.

I outline my vision for achieving this below, but am struggling with how to implement this in Python / if a better OOP style is available.

For example, in plotting.py:

class ItemPlotter(object):

    def visualisation_routine1(self):
        plt.plot(self.values)  # where values are to be acquired from the class in processing.py somehow

and in processing.py:

class Item(object):

    def __init__(self, flag):
        if flag is True:
            self.values = (1, 2, 3)
        else:
            self.values = (10, 5, 0)

        from plotting.py import ItemPlotter
        self.plots = ItemPlotter()

which results in the following command line usage:

 from processing.py import Item
 my_item = Item(flag=True)
 # Plot results
 my_item.plots.visualisation_routine1()

My actual code will be more complicated than this and potentially Item will have attributes that are large datasets, thus I expect that I need to avoid copying these for memory efficiency.

Is my vision possible, or even a Pythonic approach please? Any comments re. OOP or efficient ways to achieve this would be appreciated.

PS, I'm aiming for Py2.7 and Py3 compatibility.

like image 675
IanRoberts Avatar asked Mar 12 '26 19:03

IanRoberts


1 Answers

For convenient and memory-efficient usage, the model class should be able to inherit all the plotting methods, making them easily accessible for the user, yet keeping the code easy to maintain and read by separating scientific numerical code from visualisation code.

As Jon points out, you're actually describing composition rather than inheritance (which is the generally preferred way of doing it anyway).

One way of achieving what you want is to create an abstract class that defines the interface for an "item plotter" and inject it as a dependency to instances of Item. You can allow clients of Item to easily plot the data encapsulated by the Item instance by exposing a method that delegates plotting to the injected ItemPlotter.

This approach allows each class to respect the Single Responsibility Principle and makes the code easier to understand, maintain and test. You can define Item and ItemPlotter in separate Python modules if you prefer.

from abc import abstractmethod, ABC


class AbstractItemPlotter(ABC):
    @abstractmethod
    def plot(self, values):
        return


class ItemPlotter(AbstractItemPlotter):
    def plot(self, values):
        # plt.plot(values)
        print('Plotting {}'.format(values))
        pass


class Item(object):
    def __init__(self, flag: bool, plotter: AbstractItemPlotter):
        self._plotter = plotter
        if flag:
            self.values = (1, 2, 3)
        else:
            self.values = (10, 5, 0)

    def visualisation_routine1(self):
        self._plotter.plot(self.values)

if __name__ == '__main__':
    item = Item(flag=True, plotter=ItemPlotter())
    item.visualisation_routine1()

Output

Plotting (1, 2, 3)

Edit

This code was tested using Python 3.5.2. I can't say for sure if it will work in Python 2.7 as is.

like image 126
Tagc Avatar answered Mar 14 '26 07:03

Tagc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!