Skip to content

Instantly share code, notes, and snippets.

@rcalsaverini
Created October 8, 2012 00:16
Show Gist options
  • Save rcalsaverini/3850065 to your computer and use it in GitHub Desktop.
Save rcalsaverini/3850065 to your computer and use it in GitHub Desktop.
A Singleton metaclass in python:
class Singleton(type):
""" This is a Singleton metaclass. All classes affected by this metaclass
have the property that only one instance is created for each set of arguments
passed to the class constructor."""
def __init__(cls, name, bases, dict):
super(Singleton, cls).__init__(cls, bases, dict)
cls._instanceDict = {}
def __call__(cls, *args, **kwargs):
argdict = {'args': args}
argdict.update(kwargs)
argset = frozenset(argdict)
if argset not in cls._instanceDict:
cls._instanceDict[argset] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instanceDict[argset]
class Connection(object):
""" Simulate a connection that sends messages to a host.
Note that each host passed to the constructor will
instantiate this class only once."""
__metaclass__ = Singleton
def __init__(self, host = 'none'):
self.host = host
def send(self, msg):
print "Sent to {host}: {msg}".format(host = self.host, msg = msg)
conn1 = Connection(host = 'myhost')
conn2 = Connection(host = 'home')
conn3 = Connection(host = 'home')
assert(id(conn3) == id(conn2))
assert(id(conn1) != id(conn2))
@chermed
Copy link

chermed commented Jan 2, 2018

conn4 = Connection(8000, host = 'myhost', args=['ssl'])
This example will fail as we have an argument called args, I think you can do something like :

argdict = {'args': args, 'kwargs':kwargs}
argset = frozenset(argdict)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment