Flyweighting in Python Redux
I just expanded the Flyweighted Object class to support keyword arguments:
import weakref
import cPickle
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 = cPickle.dumps((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()