Skip to content

Instantly share code, notes, and snippets.

@omry
Created June 24, 2020 00:07
Show Gist options
  • Save omry/1009cf54feea882b7ddad002136c30cc to your computer and use it in GitHub Desktop.
Save omry/1009cf54feea882b7ddad002136c30cc to your computer and use it in GitHub Desktop.
from typing import Any, Dict
class Singleton(type):
_instances: Dict[type, "Singleton"] = {}
def instance(cls: Any, *args: Any, **kwargs: Any) -> Any:
return cls(*args, **kwargs)
def __call__(cls, *args: Any, **kwargs: Any) -> Any:
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class FooSingleton(metaclass=Singleton):
def __init__(self, num) -> None:
self.num = num
def __enter__(self):
return FooSingleton.instance()
def __exit__(self, exc_type, exc_val, exc_tb):
FooSingleton.clear()
def add(self, x):
return self.num + x
@classmethod
def clear(cls):
del Singleton._instances[FooSingleton]
@staticmethod
def instance(*args: Any, **kwargs: Any) -> "FooSingleton":
return Singleton.instance(FooSingleton, *args, **kwargs) # type: ignore
if __name__ == "__main__":
print("== context call:")
with FooSingleton.instance(20) as s:
print(s.add(5))
print("== standalone call:")
s = FooSingleton.instance(10)
print(s.add(5))
@omry
Copy link
Author

omry commented Jun 24, 2020

== context call:
25
== standalone call:
15

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