Created
August 15, 2017 04:10
-
-
Save QuantumGhost/8181e7993a17cdc0bcd08c9b9ebcc941 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Symbol: | |
__registry = {} | |
__lock = Lock() | |
__slots__ = ('name',) | |
def __new__(cls, name): | |
instance = cls.__registry.get(name) | |
if not instance: | |
with cls.__lock: | |
# A classical double-checked lock pattern. | |
# the second check is necessary | |
# considering the following procedure: | |
# t1 calls new | |
# t2 calls new | |
# t1 check registry, found symbol not exist | |
# t2 check registry, found symbol not exist | |
# t1 acquires lock, creating symbol | |
# t2 waits for lock | |
# t1 create symbol and store it in registry | |
# t2 acquire lock, create symbol and store it in registry | |
# now two symbols with same name are created, we're in trouble. | |
instance = cls.__registry.get(name) | |
if instance: | |
return instance | |
instance = super().__new__(cls) | |
instance.name = name | |
cls.__registry[name] = instance | |
return instance | |
def __init__(self, name): | |
self.name = name | |
def __eq__(self, other): | |
return id(self) == id(other) | |
def __hash__(self): | |
return hash(self.name) | |
def __str__(self): | |
return "Symbol({})".format(self.name) | |
def __repr__(self): | |
return 'Symbol("{}")'.format(self.name) | |
def __getnewargs__(self): | |
return self.name, | |
STOP = Symbol('stop') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment