I recently came across Python's metaclass concept and I am trying to enforce Singleton
for a few existing classes. I want to reuse the previously created instance when the class is instantiated again.
Here is my attempt at it. But the singleton condition doesn't seem to get enforced.
The existing class that should enforce Singleton
. I have multiple such classes like Bike, Train which inherits Vehicle
and all these should be made singleton.
from singleton import Singleton
from vehicle import Vehicle
class Car(Vehicle, object):
__metaclass__ = Singleton
def __init__(self):
print("Constructor: Car is starting")
pass
def print_car(self):
print("Car is running")
Car class inherits a Vehicle
from abc import ABC
class Vehicle(ABC):
def __init__(self):
pass
Here is my attempt at Singleton
. I used a few reference SO posts.
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
However, when I create multiple objects for Car
, I don't see singleton being enforced.
car = Car()
car.print_car()
car2 = Car()
car2.print_car()
print(car is car2) # Returns False
As I am still learning Python's metaclass and how it works, wondering what I am missing here?
All these classes (base class and derived class) are in my control and I can make changes to them. How can I achieve enforcing singleton to my sub-classes like Car
, Bike
etc?
[Update 1] Using Python 3 version of metaclass gives me the below error
from singleton import Singleton
from vehicle import Vehicle
class Car(Vehicle, object, metaclass=Singleton):
# class Car(Vehicle, object):
# __metaclass__ = Singleton
def __init__(self):
print("Constructor: Car is starting")
def print_car(self):
print("Car is running")
Error:
File "/Users/user/HelloVsCode/hello.py", line 5, in <module>
from car import Car
File "/Users/user/HelloVsCode/car.py", line 7, in <module>
class Car(Vehicle, object, metaclass=Singleton):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases