1

I am programming a bokeh application. I want to split the functionalities into different files. But I want to have some attributes accesible from every class, these attributes should be shared and always updated. For example an attribute which stores a dataframe that all the plots are going to use. So I think I have at least two possible solutions:

  • Use a big class and include the attributes and methods of other files:

    class Bigclass(object):
    
        from bk_plots import p1, p2, p3
        from bk_data import d1, d2, d3
        from bk_layout import ly1, ly2
        from bk_events import ev1, ev2
        # unfortunately, "from classdefn import *" is an error or warning
    
        num = 42   # add more members here if you like
    

    Note: this solution was copied from here (partial classes)

  • Or I could use inheritance. The parent will have the shared attributes. The perk of this system is that I would need to send the rest of the object references to every subclass

    class Parent():
        shared = 'parent'
    
    class Plot(Parent):
        def __init__(self):
            Parent.shared = 'plots'   # update class variable from this class
                                    # I would need to have references to the objects of other classes
    
    class Data(Parent):
        def __init__(self):
            Parent.shared = 'second'
    
    # [...]
    

Is there a better way to do this? Which option will bring me less problems?

ChesuCR
  • 9,352
  • 5
  • 51
  • 114
  • 1
    what I did in one case was to create a data class which would hold the dataframe and have methods to manipulate / update it, then one or more plot classes which would be passed that data object. In my case the plot objects would be the ones plotted (static or server with two different methods) but it could also return the bokeh plot object to be used further in assembling the app. – Alex Mar 08 '18 at 01:31
  • Thank you for your point. So, in your case, if the plots are already plotted, you can still update the data because you can call the methods of the data object within the plot class, right? Similar to my second option but also sending the data object reference and avoiding the parent object. – ChesuCR Mar 08 '18 at 09:26
  • I have answered my own question @Alex. Take a look at it. – ChesuCR Apr 02 '18 at 16:28

1 Answers1

1

Finally I have created an my_bokeh_app folder. There I have an __init__.py file with this content for the initialization:

from my_bokeh_app.bokeh_data import BokehData
from my_bokeh_app.bokeh_plots import BokehPlots
from my_bokeh_app.bokeh_table import BokehDataTable
from my_bokeh_app.bokeh_events import BokehEvents
from my_bokeh_app.bokeh_layout import BokehLayout

BokehData()
BokehPlots()
BokehDataTable()
BokehEvents()
BokehLayout()

I have created a Class to share data among all the objects. This is the class:

class BokehSharedData(object):
    # ------------------- CLASS VARIABLES ---------------------- #
    # This variables are shared. So all the children can access them

    data_source = None

    bk_layout = None
    bk_data = None
    bk_plot = None
    bk_table = None
    bk_events = None

In every class I make a reference to the BokehSharedData class. I also inherit from that class to access to the class variables.

from my_bokeh_app.bokeh_shared_data import BokehSharedData

class BokehData(BokehSharedData):
    def __init__(self, **kwargs):
        self.env = BokehSharedData
        self.env.bk_data = self

        # If for example I want to access to the source attribute from the rest of objects
        # I could make this shortcut on the shared class
        self.env.data_source = ColumnDataSource(...)

    def update_data_source(self):

        # [...]

And I could read the shared attributes or execute methods from other object:

from my_bokeh_app.bokeh_shared_data import BokehSharedData

class BokehPlots(BokehSharedData):
    def __init__(self, **kwargs):
        self.env = BokehSharedData
        self.env.bk_plots = self

        # I could use self.env.data_source here or run some method of BokehData class like this

        self.env.bk_data.update_data_source()

The complete app where you can see all the classes working is here

ChesuCR
  • 9,352
  • 5
  • 51
  • 114
  • Do you run it from the console? Do you have a working minimal example? – Mohamed Ibrahim Nov 11 '19 at 16:39
  • @MohamedIbrahim The code in the answer by itself does not work. I have written it just to give an idea. The whole project that I have made, following this example, is [here](https://github.com/ocean-data-qc/ocean-data-qc). Check [the ocean_data_qc folder](https://github.com/ocean-data-qc/ocean-data-qc/tree/master/ocean_data_qc/bokeh_models) where I have stored all the bokeh classes – ChesuCR Nov 11 '19 at 17:45
  • However I keep many objects alive all the time. I do not really know if this is the best way to proceed, but I did not find any other better way – ChesuCR Nov 11 '19 at 17:49