Python: use the same class instance in multiple modules

Viewed 5302

I have a class called EventManager, and am calling this class in each module I have. I thought of creating a single instance of the EventManager in the main file, and use that instance in each module. My questions are:

  • Is this the right way in my case? Note that I don't want to create multiple instances of the EventManager as it parses a file each time it is called, and that file can contain large amount of data.
  • what is the best way to do it, given that I want less memory usage?
2 Answers

You could use a singleton. Here is a simple example:

def singleton(cls):
    return cls()

@singleton
class EventManager:
    def __init__(self):
        self.events = []
    def add_event(self, event):
        self.events.append(event)
    def print_events(self):
        print("Events : {}".format(self.events))

EventManager.add_event(0)
EventManager.add_event(1)
EventManager.add_event(2)
EventManager.print_events()

Output:

Events : [0, 1, 2]

Note that everything still works as expected when the singleton is imported and used in other modules.


EDIT

You asked :

The thing is that I initialize the class with a variable like EventManager(var), what shall I do in this case?

The class will be instantiated right after its definition, i.e. the first time the module containing EventManager is imported. Since EventManager is a singleton, I don't think there is a point initializing the singleton with a variable. Even though it is possible:

def singleton_with_args(*args, **kwargs):
    def wrapper(cls):
        return cls(*args, **kwargs)
    return wrapper

@singleton_with_args(0)
class EventManager:
    def __init__(self, first_event):
        self.events = [first_event]
    def add_event(self, event):
        self.events.append(event)
    def print_events(self):
        print("Events : {}".format(self.events))

EventManager.add_event(1)
EventManager.add_event(2)
EventManager.add_event(3)
EventManager.print_events()

Output:

Events : [0, 1, 2, 3]

It works but as I said, I don't think it's useful. You could as well use methods or module variables to initialize your singleton.

This question is old but it was the first that came up for me, so I think it might be good to mention for others that there is a lot of talk about singletons being antipatterns, not pythonic etc.

After searching for a while, I think the best method is to use a metaclass:

In general, it makes sense to use a metaclass to implement a singleton. A singleton is special because is created only once, and a metaclass is the way you customize the creation of a class. Using a metaclass gives you more control in case you need to customize the singleton class definitions in other ways.

Related