Skip to content

Instantly share code, notes, and snippets.

@jamuspsi
Created May 31, 2019 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamuspsi/375bdf12a53331337ac0ceb5fe23de11 to your computer and use it in GitHub Desktop.
Save jamuspsi/375bdf12a53331337ac0ceb5fe23de11 to your computer and use it in GitHub Desktop.
print "Singleton is ", Singleton
print "Singleton class is ", Singleton.__class__
print "Singleton instance is ", Singleton()
print "Singleton instance class is ", Singleton().__class__
a = Singleton()
b = Singleton()
assert a is b
class One(Singleton):
def __init__(self):
self.x = 3
print "Init ran"
def run(self, *args, **kwargs):
print locals()
@classmethod
def cm(cls, *args, **kwargs):
print "Classmethod, ", locals()
@staticmethod
def sm(*args, **kwargs):
print "Staticmethod, ", locals()
c = One()
d = One()
assert c is d
c.run(1,2,3, a=4)
c.sm(1,2,3, a=4)
c.cm(1,2,3, a=4)
class C(object):pass
c.__class__.__bases__ = (C,)
print "One's class is ", One.__class__
c.__metaclass__ = type
# One.__class__ = type
# print "One is ", One, " dict is ", One.__dict__
print "One bases are ", One.__bases__
print "One is a singletonmeta", isinstance(One, type(Singleton))
e = One()
assert e is d
def Singleton():
instancecache = {}
class SingletonMeta(type):
def __new__(cls, name, bases, d):
if '__init__' not in d:
raise ValueError('You must define an __init__ for any singleton class.')
def validate_class(cls):
assert isinstance(cls, SingletonMeta)
def validating_method(v):
def wrapped(self, *args, **kwargs):
print "Calling method ", v
validate_class(type(self))
return v(self, *args, **kwargs)
return wrapped
def validating_classmethod(v):
def wrapped(cls, *args, **kwargs):
validate_class(cls)
return v(cls, *args, **kwargs)
return wrapped
def validating_staticmethod(v):
def as_classmethod(cls, *args, **kwargs):
validate_class(cls)
return v(*args, **kwargs)
return classmethod(as_classmethod)
for k, v in d.iteritems():
if callable(v):
if isinstance(v, staticmethod):
d[k] = validating_staticmethod(v)
elif isinstance(v, classmethod):
d[k] = validating_classmethod(v)
else:
d[k] = validating_method(v)
newclass = super(SingletonMeta, cls).__new__(cls, name, bases, d)
return newclass
def __call__(cls, *args, **kwargs):
assert isinstance(cls, SingletonMeta)
if id(cls) not in instancecache:
instancecache[id(cls)] = super(SingletonMeta, cls).__call__(*args, **kwargs)
return instancecache[id(cls)]
class Singleton(object):
__metaclass__ = SingletonMeta
def __init__(self):
pass
def __getattribute__(self, *args, **kwargs):
assert isinstance(type(self), SingletonMeta)
return super(Singleton, self).__getattribute__(*args, **kwargs)
def __setattribute__(self, *args, **kwargs):
assert isinstance(type(self), SingletonMeta)
return super(Singleton, self).__getattribute__(*args, **kwargs)
return Singleton
Singleton = Singleton()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment