Home > Software engineering >  Why is the insantiation of this singleton class giving different values
Why is the insantiation of this singleton class giving different values

Time:01-01

Why do these two statement give different outcomes...

  • print(Database().id == Database().id) (which gives False)
  • but it gives True this way
d1 = Database()
d2 = Database()
print(d1.id == d2.id)

here's the entire code:

import random

class Database:
    initialized = False

    def __init__(self):
        self.id = random.randint(1, 101)

    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Database, cls).__new__(cls, *args, **kwargs)
        return cls._instance



print(Database().id == Database().id)
# False

d1 = Database()
d2 = Database()
print(d1.id == d2.id)
# True

CodePudding user response:

__new__() always calls __init__() if the returned instance is of the correct class. This means, every Database() call is still going through and setting a new random value to id.

This id is an instance variable that you have defined, it will not really affect the result of id(), which is why if you do

print(Database() is Database())

it will return True even though the id check returned false. The instance is the same, you just changed id value in between, so they evaluate as False.

In the second case, because the instance is the same, both of them get the value generated by __init__() when you assign d2. You can confirm this by adding a print(d1.id) before and after d2 is assigned.

You need to make use of the initialized boolean to correctly skip the code in __init__()

import random

class Database:
    initialized = False

    def __init__(self):
        if not self.initialized:
            self.id = random.randint(1, 101)
            self.initialized = True

    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Database, cls).__new__(cls, *args, **kwargs)
        return cls._instance

Take a look at issue with singleton python call two times __init__ if you want to see other implementations of a singleton class or alternative approaches that avoid singleton entirely.

  • Related