Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share a singleton across modules

Given two modules, main and x with the following contents:

main:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        cls._instance.x = 10
        return cls._instance
uvw = Singleton()

if __name__ == "__main__":
    print(id(uvw))
    uvw.x += 10
    print(uvw.x)
    import x

and x, respectively:

import main

print(id(main.uvw))
print(main.uvw.x)

I would now expect that executing main would yield the same IDs and the value twenty in both instances, but what I get is this:

$ python main.py
140592861777168
20
140592861207504
10

Is there any way I can ensure that uvw is the same object at both places?

like image 403
dom0 Avatar asked Nov 11 '12 12:11

dom0


1 Answers

I reckon the problem is that your Singleton class is somehow being reloaded, and thus loses its _instance field in the second module.


I think this will work:

singleton.py:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        cls._instance.x = 10
        return cls._instance

a.py:

from singleton import Singleton
uvw = Singleton()
print(id(uvw))
uvw.x += 10
print(uvw.x)

b.py:

from singleton import Singleton
uvw = Singleton()
print(id(uvw))
uvw.x += 10
print(uvw.x)

main.py

import a
import b
like image 182
Eric Avatar answered Sep 27 '22 20:09

Eric