7

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?
user1894963
  • 635
  • 3
  • 11
  • 18

2 Answers2

10

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.

Vincent
  • 12,919
  • 1
  • 42
  • 64
  • what is cls in the singleton function ? Do you mean EventManager ? – user1894963 Dec 04 '13 at 12:31
  • `singleton` is a decorator. When you write `@singleton` right before your class definition, it's exactly like writing `EventManager = singleton(EventManager)` right after your class definition. – Vincent Dec 04 '13 at 12:38
  • Now, If I want to use EventManager in another module in another file. How can I do that ? How can i call it ? I tried to import the file then: – user1894963 Dec 04 '13 at 12:47
  • file.EventManager() ... but shows me an error saying EventManager instance has no __call__ method – user1894963 Dec 04 '13 at 12:48
  • You have to use `file.EventManager` instead of `file.EventManager()` because `file.EventManager` is already an instance of your class `EventManager` (thanks to the singleton decorator) – Vincent Dec 04 '13 at 12:54
  • The thing is that I initialize the class with a variable like EventManager(var), what shall I do in this case? – user1894963 Dec 04 '13 at 19:36
0

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.

Simon TheChain
  • 277
  • 1
  • 16