Jai K
Jai K

Reputation: 395

Best approach to avoid repetitive database connection in Object Oriented Programming

Here is the sample code in Python.

[sample.py]

class MyApp(object):
     
      def __init__(self):
         self.instance = None

         self.connect()


    def connect(self):
        if self.instance is None:
            print('Connecting to DB...')
            self.instance = 1 # Assume connected
        return self.instance

[A.py]

from sample import MyApp
from B import again

a = MyApp()
again()

[B.py]

from sample import MyApp

def again():
    b = MyApp()

Wouldn't like to call the connect() method explicitly by MyApp().connect(), so that added in __init__ method itsef. (Please do advice if any better approach is available, Is __new__() will be helpful in this context?)

[Output]

>> python A.py
Connecting to DB...
Connecting to DB...

[Expected]

>> python A.py
Connecting to DB...

I don't want to create an instance again and again. Any suggestion/advise would be grateful. Thanks,

Upvotes: 1

Views: 215

Answers (1)

aneroid
aneroid

Reputation: 15962

The problem is self.instance is on the instance. What you want is to put that as a class attribute so that all the instances have that info. To access it, use self.__class__.instance. Also, in Python3, classes don't need to inherit from object.

>>> class MyApp:
...     instance = None
...
...     def __init__(self):
...         self.connect()
...
...     def connect(self):
...         if self.__class__.instance is None:
...             print('connecting')
...             self.__class__.instance = 1
...
>>>
>>> a = MyApp()  # will connect the first time
connecting
>>> b = MyApp()  # no new connection
>>> a.connect()  # no new connection
>>> b.connect()  # no new connection

(Btw, in this case especially, instance is not a good name, since it's the exact opposite. Use connected = True/False instead.)

And if connect() doesn't need access to other instance variables, it can be a classmethod and use cls.instance:

>>> class ... # as before
...     @classmethod
...     def connect(cls):  # cls is the class
...         if cls.instance is None:
...             print('connecting')
...             cls.instance = 1

Upvotes: 1

Related Questions