Created
March 6, 2013 14:56
-
-
Save jathanism/5099826 to your computer and use it in GitHub Desktop.
Implementations of the Highlander (Singleton) and Borg (Monostate) patterns for keeping globally accessible data.
This file contains hidden or 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
| """ | |
| highborg.py - Highlander vs. Borg. | |
| Implementations of the Highlander (Singleton) and Borg (Monostate) patterns for | |
| keeping globally accessible data. | |
| New-Style Highlander credit: | |
| http://code.activestate.com/recipes/66531-singleton-we-dont-need-no-stinkin-singleton-the-bo/#c22 | |
| New-Style Borg credit: | |
| http://code.activestate.com/recipes/66531-singleton-we-dont-need-no-stinkin-singleton-the-bo/#c20 | |
| """ | |
| class Highlander(object): | |
| """ | |
| Shares *identity* between instances (aka the "Singleton" pattern). | |
| Only one instance can exist globally per subclass. Identity tests (``is``, | |
| ``id(foo) == id(bar)``) will return ``True``. All new instances have | |
| ``self`` replaced with the master instance. | |
| A change to any internals affects all references to the instance. | |
| """ | |
| def __new__(cls, *p, **k): | |
| if not '_instance' in cls.__dict__: | |
| cls._instance = object.__new__(cls) | |
| return cls._instance | |
| def __repr__(self): | |
| return '%s({%s})' % (self.__class__.__name__, | |
| str(', '.join('%s : %s' % (repr(k), repr(v)) for | |
| (k, v) in self.__dict__.iteritems()))) | |
| class NetDevices(Highlander): | |
| def __init__(self, name, *args, **kwargs): | |
| super(NetDevices, self).__init__(*args, **kwargs) | |
| self.name = name | |
| class Borg(object): | |
| """ | |
| Shares *state* between instances (aka the "Monostate" pattern). | |
| Each instance shares the same internal state per subclass. Identity tests | |
| will return ``False``. All new instances have their dict referencing the | |
| state dict in the class object. | |
| A change to any internals affects all instances. | |
| """ | |
| _state = {} | |
| def __new__(cls, *p, **k): | |
| self = object.__new__(cls, *p, **k) | |
| self.__dict__ = cls._state | |
| return self | |
| def __repr__(self): | |
| return '%s({%s})' % (self.__class__.__name__, | |
| str(', '.join('%s: %s' % (repr(k), repr(v)) for | |
| (k, v) in self.__dict__.iteritems()))) | |
| class BorgDevices(Borg): | |
| def __init__(self, *args, **kwargs): | |
| data = args[0] if args else kwargs.get('data', {}) | |
| self.__dict__.update(data) | |
| super(BorgDevices, self).__init__(*args, **kwargs) | |
| if __name__ == '__main__': | |
| print 'Highlander tests...' | |
| print '=' * 10 | |
| nd = NetDevices('foo') | |
| print 'nd.name', nd.name | |
| fd = NetDevices('boo') | |
| print 'fd.name', fd.name | |
| print 'nd.name', nd.name | |
| print 'Borg tests...' | |
| print '=' * 10 | |
| bd = BorgDevices({'foo': 'bar', 'spam': 'eggs'}) | |
| print 'bd.foo', bd.foo | |
| bd2 = BorgDevices() | |
| print 'bd2.foo', bd2.foo | |
| bd3 = BorgDevices({'bacon': 'win', 'apples': 'oranges'}) | |
| print 'bd3.bacon', bd3.bacon | |
| print 'bd.bacon', bd.bacon |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment