Created
May 10, 2012 19:01
-
-
Save juliengrenier/2655143 to your computer and use it in GitHub Desktop.
NullProxy and Borg objects
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
class NullProxy(object): | |
"""Pretend you have a model object with three attributes: | |
class Person(object): | |
name = String(40) | |
age = Integer() | |
email = Email() | |
And have a sub-class adding extra attributes: | |
class SpecialPerson(Person): | |
role = "true believer" | |
If you want to safely treat Person and all subclasses the same: | |
me = NullProxy(Person(name="Alice")) | |
me.role == None | |
""" | |
def __init__(self, obj=None, default=None, parent=None): | |
self.obj = obj | |
self.default = default | |
self.parent = parent | |
def __call__(self, *args, **kw): | |
if not hasattr(self.obj, '__call__'): | |
raise TypeError("'{0!r}' object is not callable".format(self.obj)) | |
value = self.obj(*args, **kw) | |
if value is None: | |
return self.parent | |
return value | |
def __getattr__(self, name): | |
try: | |
return NullProxy(getattr(self.obj, name), self.default, self.obj) | |
except AttributeError: | |
return NullProxy(self.default, self.default, self.obj) | |
def __setattr__(self, name, value): | |
if self.obj is None: | |
raise AttributeError("Can not write to null object.") | |
setattr(self.obj, name, value) | |
class Borg(object): | |
__collective__ = None | |
def __init__(self): | |
name = '_'.join(reversed([i.__name__ for i in type(self).mro()])) | |
if Borg.__dict__.setdefault('__collective_{0}__'.format(name), None) is None: | |
Borg.__dict__[name] = self.__dict__ | |
else: | |
self.__dict__ = Borg.__dict__[name] | |
def __eq__(self, other): | |
return self.__dict__ is other.__dict__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment