Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

what is the correct OOP method updating instance variables in python

I have two classes that required app_config (in my case app_config should globally available in all classes within my project).

Class1 required app_config and it provides few more inputs that I need to update again in app_config, like wise in class2.

Later I need to update app_config in both classes 1 and 2.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

what is correct method of updating instance variable. Does I am doing correctly or Do I need to consider differently?

import requests 
app_config = {
    "MaxThreadCount": 10,
    "BaseURL": "https://google.com",
    "DB": "some db ip"
}

class Class1():
    def __init__(self, app_config):
        self.app_config = app_config
    
    def get_few_more_configs_in_class1(self):
        var1 = requests.get(self.app_config["BaseURL"])
        print("get few data")
        return {"class-1": "some inputs"}

    def set_appconfig(self, app_config):
        self.app_config = app_config

class Class2():
    def __init__(self, app_config):
        self.app_config = app_config
    
    def gather_few_more_configs_in_class2(self, inputs_from_class1):
        print("connect to db")
        return {"db-inputs": "some more inpus"}
    
    def set_appconfig(self, app_config):
        self.app_config = app_config

c1 = Class1(app_config=app_config)
c2 = Class2(app_config=app_config)
class1_inputs = c1.get_few_more_configs_in_class1()
class2_inputs = c2.gather_few_more_configs_in_class2(class1_inputs)
app_config.update(class1_inputs)
app_config.update(class2_inputs)

c1.set_appconfig(app_config=app_config)
c2.set_appconfig(app_config=app_config)

        

>Solution :

Here’s a few changes that make more sense:

import requests

app_config = {
    "MaxThreadCount": 10,
    "BaseURL": "https://google.com",
    "DB": "some db ip"
}


class Class1():
    def __init__(self, cfg):  # you want to avoid shadowing something global
        # since you have a setter, discourage direct access
        self._cfg = cfg  

    def get_few_more_configs_in_class1(self):
        var1 = requests.get(self.app_config["BaseURL"])
        print("get few data")
        # no need to update after return, just update directly
        self._cfg.update({"class-1": "some inputs"})
    
    # this is a better way to expose and allow setting, with a property
    @property
    def app_config(self):
        return self._cfg
    
    @app_config.setter
    def app_config(self, cfg):
        self._cfg = cfg


class Class2():
    def __init__(self, cfg):
        self._cfg = cfg

    def gather_few_more_configs_in_class2(self):
        print("connect to db")
        # here, you can use whatever was previously set in your `app_config`
        print("using", self._cfg['class-1'])
        self._cfg.update({"db-inputs": "some more inpus"})

    # this is a better way to expose and allow setting, with a property
    @property
    def app_config(self):
        return self._cfg

    @app_config.setter
    def app_config(self, cfg):
        self._cfg = cfg


c1 = Class1(app_config)
c2 = Class2(app_config)

c1.get_few_more_configs_in_class1()
# no need to pass stuff in, already has the config
c2.gather_few_more_configs_in_class2()  

However, since you apparently want to use your app_config as more of a shared app state, perhaps call it that? And globals are generally best avoided, so you could just set stuff up in a main(). And finally, if you have multiple classes with the same logic, why not use inheritance?

import requests


class StateSharing:
    def __init__(self, state: dict):
        self._state = state

    @property
    def state(self) -> dict:
        return self._state

    @state.setter
    def state(self, state: dict):
        self._state = state


class Class1(StateSharing):
    def get_few_more_configs_in_class1(self):
        requests.get(self.state["BaseURL"])
        print("get few data")
        self._state.update({"class-1": "some inputs"})


class Class2(StateSharing):
    def __init__(self, state: dict, something_else: str):
        super().__init__(state)
        self.something_else = something_else

    def gather_few_more_configs_in_class2(self):
        print("connect to db")
        print("using", self._state['class-1'])
        self._state.update({"db-inputs": "some more inpus"})


def main():
    state = {
        "MaxThreadCount": 10,
        "BaseURL": "https://google.com",
        "DB": "some db ip"
    }
    c1 = Class1(state)
    c2 = Class2(state, 'something!')

    c1.get_few_more_configs_in_class1()
    c2.gather_few_more_configs_in_class2()


if __name__ == '__main__':
    main()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading