def reify_object(o, s): """ Reify a Python object with a substitution >>> from logpy.unifymore import reify_object >>> from logpy import var >>> class Foo(object): ... def __init__(self, a, b): ... self.a = a ... self.b = b ... def __str__(self): ... return "Foo(%s, %s)"%(str(self.a), str(self.b)) >>> x = var('x') >>> f = Foo(1, x) >>> print f Foo(1, ~x) >>> print reify_object(f, {x: 2}) Foo(1, 2) """ obj = object.__new__(type(o)) d = reify_dict(o.__dict__, s) if d == o.__dict__: return o obj.__dict__.update(d) return obj
def reify_object_attrs(o, s, attrs): """ Reify only certain attributes of a Python object >>> from logpy.unifymore import reify_object_attrs >>> from logpy import var >>> class Foo(object): ... def __init__(self, a, b): ... self.a = a ... self.b = b ... def __str__(self): ... return "Foo(%s, %s)"%(str(self.a), str(self.b)) >>> x = var('x') >>> y = var('y') >>> f = Foo(x, y) >>> print f Foo(~x, ~y) >>> print reify_object_attrs(f, {x: 1, y: 2}, ['a', 'b']) Foo(1, 2) >>> print reify_object_attrs(f, {x: 1, y: 2}, ['a']) Foo(1, ~y) This function is meant to be partially specialized >>> from functools import partial >>> reify_Foo_a = partial(reify_object_attrs, attrs=['a']) attrs contains the list of attributes which participate in reificiation """ obj = object.__new__(type(o)) d = dict(zip(attrs, map(o.__dict__.get, attrs))) # dict with attrs d2 = reify_dict(d, s) # reified attr dict if d2 == d: return o obj.__dict__.update(o.__dict__) # old dict obj.__dict__.update(d2) # update w/ reified vals return obj
def test_reify_dict(): x, y = var(), var() s = {x: 2, y: 4} e = {1: x, 3: {5: y}} assert reify_dict(e, s) == {1: 2, 3: {5: 4}}