Skip to content

Instantly share code, notes, and snippets.

@simon-engledew
Created July 10, 2009 13:59
Show Gist options
  • Save simon-engledew/144529 to your computer and use it in GitHub Desktop.
Save simon-engledew/144529 to your computer and use it in GitHub Desktop.
import weakref
def generate_key(o):
if hasattr(o, 'items'):
return generate_key(sorted(o.items(), lambda a, b: cmp(a[0], b[0])))
if hasattr(o, '__iter__'):
return tuple(generate_key(v) for v in o)
return o
class FlyweightedObject(object):
_pool = weakref.WeakValueDictionary()
def __new__(klass, *args, **kwargs):
if not hasattr(klass.__init__, 'im_func'): raise 'cannot flyweight an object which has no python constructor'
arguments = {}
constructor = klass.__init__.im_func
arguments_missing = constructor.func_code.co_argcount - len(args) - 1
if arguments_missing > 0:
args += constructor.func_defaults[-arguments_missing:]
varnames = constructor.func_code.co_varnames[1:]
for i in range(len(varnames)):
varname = varnames[i]
arguments[varname] = kwargs.get(varname, args[i])
key = generate_key((klass, arguments))
instance = klass._pool.get(key, None)
if instance is None:
instance = object.__new__(klass)
klass._pool[key] = instance
return instance
def __getnewargs__(self):
if hasattr(self.__class__.__init__, 'im_func'):
constructor = self.__class__.__init__.im_func
return tuple(getattr(self, attr) for attr in constructor.func_code.co_varnames[1:])
return tuple()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment