0

I am using the following solution to maintain a list of classes instances: https://stackoverflow.com/a/12102163

Now I want to use that list to make sure that there is always only one instance of the class. Renewed initializations of the class should return the one existing instance.

The code I have is:

class MyClass:

    instances = []

    def __init__(self):
        if not MyClass.instances:
            self.data=1234
        else:
            self = MyClass.instances[0]

So:

>> a=MyClass()
>> a.data
1234

And b=MyClass() should return the same instance as a. This is not working. What is wrong with my code?

EDIT: OK, so it turns out I am looking for the singleton pattern, but couldn't recreate it myself. Can anyone please explain why my code does not work?

Community
  • 1
  • 1
boadescriptor
  • 735
  • 2
  • 9
  • 29
  • 2
    related: [Is there a simple, elegant way to define Singletons in Python?](http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python) – jfs Apr 17 '15 at 11:29
  • To answer the question at the end: what's wrong with your code, is that `self` is just a local variable in `__init__`. Assigning a value to it doesn't change what value is returned from the call to `MySelf()`. – Steve Jessop Apr 17 '15 at 11:29
  • 1
    Using singletons (and particularly using singletons in Pythong) seem to be... _discouraged_ lately... See http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons and http://stackoverflow.com/questions/1318406/why-is-the-borg-pattern-better-than-the-singleton-pattern-in-python – Savir Apr 17 '15 at 11:32

3 Answers3

2

Here's an example of the Singleton metaclass recipe. This example is from Ch. 9 of The Python Cookbook.

class Singleton(type):
    def __init__(self, *args, **kwargs):
        self.__instance = None
        super().__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self.__instance is None:
            self.__instance = super().__call__(*args, **kwargs)
            return self.__instance
        else:
            return self.__instance

# Example
class Spam(metaclass=Singleton):
    def __init__(self):
        print('Creating Spam')


if __name__ == '__main__':
    a = Spam()
    b = Spam()
    assert a is b
Deacon
  • 3,615
  • 2
  • 31
  • 52
1

Going on your code line and your style. You can make following modifications:-

class MyClass:
    instance = None
    def __init__(self):
        self.data=1234
        MyClass.instance = self

def get_myclass():
    if MyClass.instance:
        return MyClass.instance
    return MyClass()

get_myclass would be a wrapper function for creating class objects. Trying the code.

>>> import instance
>>> a=instance.get_myclass()
>>> b=instance.get_myclass()
>>> a is b
True
Barun Sharma
  • 1,452
  • 2
  • 15
  • 20
0

There's actually a quite simple solution to use the same instance of a class in Python. Here's a demo example:

#### module1.py ####

class MyClass1:
    ...

# Create an instance of the class in the same module!
my_class_1 = MyClass1()


#############################################################################
#############################################################################


#### module2.py ####

# Here import the instance (not the class!) from module1
from module1 import my_class_1

class MyClass2:
    # Do stuff to my_class_1
    ...


#############################################################################
#############################################################################


#### module3.py ####

# Here also import the instance (not the class!) from module1
from module1 import my_class_1

class MyClass3:
    # Also do stuff to my_class_1
    ...

In the example above, no matter which module (whether module2.py or module3.py) changes data of the my_class_1 instance, the changed data is reflected in both modules synchronously.

Boštjan Mejak
  • 827
  • 9
  • 23