Skip to content

Instantly share code, notes, and snippets.

@AndersonFirmino
Forked from wowkin2/SingletonMongoClient.py
Created February 22, 2018 03:35
Show Gist options
  • Save AndersonFirmino/15587c4997af32280fdb70c470838586 to your computer and use it in GitHub Desktop.
Save AndersonFirmino/15587c4997af32280fdb70c470838586 to your computer and use it in GitHub Desktop.
Python Singleton with parameters (so the same parameters get you the same object) with support to default arguments and passing arguments as kwargs (but no support for pure kwargs).
"""
Python Singleton with parameters (so the same parameters get you the same object)
with support to default arguments and passing arguments as kwargs (but no support for pure kwargs).
And implementation for MongoClient class from pymongo package.
"""
from pymongo import MongoClient
import inspect
class Singleton(type):
""" Simple Singleton that keep only one value for all instances
"""
def __init__(cls, name, bases, dic):
super(Singleton, cls).__init__(name, bases, dic)
cls.instance = None
def __call__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
return cls.instance
class SingletonArgs(type):
""" Singleton that keep single instance for single set of arguments. E.g.:
assert SingletonArgs('spam') is not SingletonArgs('eggs')
assert SingletonArgs('spam') is SingletonArgs('spam')
"""
_instances = {}
_init = {}
def __init__(cls, name, bases, dct):
cls._init[cls] = dct.get('__init__', None)
def __call__(cls, *args, **kwargs):
init = cls._init[cls]
if init is not None:
key = (cls, frozenset(
inspect.getcallargs(init, None, *args, **kwargs).items()))
else:
key = cls
if key not in cls._instances:
cls._instances[key] = super(SingletonArgs, cls).__call__(*args, **kwargs)
return cls._instances[key]
class SingletonMongoClient(object):
""" Class based on Singleton type to work with MongoDB connections
"""
__metaclass__ = SingletonArgs
def __init__(self, url, db_name=None):
if db_name:
self.connection = MongoClient(url)[db_name]
else:
self.connection = MongoClient(url).get_default_database()
def connection(self):
return self.connection
def db_init(db_name=None):
url = 'mongodb://localhost:27017/'
c = SingletonMongoClient(url, db_name).connection
return c
def tests():
class A(object):
__metaclass__ = SingletonArgs
FOO = 'bar'
assert A() is A()
class B(object):
__metaclass__ = SingletonArgs
def __init__(self, key):
self.key = key
assert B('key1') is B('key1')
assert B('key1') is not B('key2')
class C(object):
__metaclass__ = SingletonArgs
def __init__(self, key=None):
self.key = key
assert C() is C()
assert C() is C(None)
assert C(None) is C(key=None)
assert C() is C(key=None)
assert C() is not C('key')
assert C('key') is C('key')
assert C('key') is C(key='key')
assert C('key1') is not C(key='key2')
assert C(key='key1') is not C(key='key2')
class D(object):
__metaclass__ = SingletonArgs
def __init__(self):
pass
class E(object):
__metaclass__ = SingletonArgs
def __init__(self):
pass
assert D() is not E()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment