Python Object Notation (PyON)


2008/11/4 Greg Ewing <greg.ewing@canterbury.ac.nz>:
I implemented a rough version of dumps for fun on sunday, and I decided to let recursive / mutually recursive object be represented in this manner. Here are some examples below. >>> print dumps([1, 2, 1]) [1, 2, 1] Recursive objects are represented 'declaratively' >>> x = [1, 2] >>> y = [x, 'a', x] >>> print dumps(y) sym0 = [1, 2] [sym0, 'a', sym0] Mutually recursive objects also: >>> x.append(y) >>> print dumps((x, y)) sym0 = [1, 2, sym1] sym1 = [sym0, 'a', sym0] (sym0, sym1) Some examples with dictionaries >>> d = {'foo': (1, 2)} >>> print dumps(d) {'foo': (1, 2)} >>> d['me'] = d >>> print dumps(d) sym0 = {'me': sym0, 'foo': (1, 2)} sym0 An example with a class >>> class A(object): pass ... >>> a = A() >>> a.my = 'spam' >>> a.oh = (3, a) >>> print dumps(a) sym0 = A(my='spam', oh=(3, sym0)) sym0 Implementing this gave me the idea of extending it to representing object 'given' some definition. E.g. given that a='hello', then ['hello', 'world'] can be represented as [a, 'world']. This could be useful as when 'pickling' an object sometimes you end up pickling a lot of the state of the program, which is not necessary as you know it will not vary. Or sometimes you would like to pickle something 'modulo' some state. E.g. >>> print dumps(['hello', 'world'], a='hello') [a, 'world'] For hashable types, equal objects will be factored: >>> t = (1, 2) >>> print dumps(((1, 2), (1, 2)), u=(1, 2)) (u, u) >>> print dumps((t, (1, 2)), u=(1, 2)) (u, u) For non hashable types, this is not the case unless the objects are actually the same object: >>> l = [1, 2] >>> print dumps((l, l), mylist=l) (mylist, mylist) >>> print dumps((l, [1, 2]), mylist=l) (mylist, [1, 2]) One last example: >>> a = 3 >>> b = [1, 2] >>> class C(object): pass ... >>> c = C() >>> c.x = a, b >>> b.append(c) >>> print dumps(c) sym0 = C(x=(3, [1, 2, sym0])) sym0 >>> c.y={a:b} >>> print dumps(c) sym0 = C(y={3: sym1}, x=(3, sym1)) sym1 = [1, 2, sym0] sym0 >>> print dumps(b) sym0 = [1, 2, C(y={3: sym0}, x=(3, sym0))] sym0 >>> print dumps(b, c=c) [1, 2, c] -- Arnaud

Arnaud Delobelle wrote:
Careful -- hashability is not necessarily the same thing as immutability. It's possible for an object to be hashable while still having mutable state, as long as the mutable state isn't included in the criteria for equality. But an application may still care about the identity of such objects. -- Greg

2008/11/4 Greg Ewing <greg.ewing@canterbury.ac.nz>:
I implemented a rough version of dumps for fun on sunday, and I decided to let recursive / mutually recursive object be represented in this manner. Here are some examples below. >>> print dumps([1, 2, 1]) [1, 2, 1] Recursive objects are represented 'declaratively' >>> x = [1, 2] >>> y = [x, 'a', x] >>> print dumps(y) sym0 = [1, 2] [sym0, 'a', sym0] Mutually recursive objects also: >>> x.append(y) >>> print dumps((x, y)) sym0 = [1, 2, sym1] sym1 = [sym0, 'a', sym0] (sym0, sym1) Some examples with dictionaries >>> d = {'foo': (1, 2)} >>> print dumps(d) {'foo': (1, 2)} >>> d['me'] = d >>> print dumps(d) sym0 = {'me': sym0, 'foo': (1, 2)} sym0 An example with a class >>> class A(object): pass ... >>> a = A() >>> a.my = 'spam' >>> a.oh = (3, a) >>> print dumps(a) sym0 = A(my='spam', oh=(3, sym0)) sym0 Implementing this gave me the idea of extending it to representing object 'given' some definition. E.g. given that a='hello', then ['hello', 'world'] can be represented as [a, 'world']. This could be useful as when 'pickling' an object sometimes you end up pickling a lot of the state of the program, which is not necessary as you know it will not vary. Or sometimes you would like to pickle something 'modulo' some state. E.g. >>> print dumps(['hello', 'world'], a='hello') [a, 'world'] For hashable types, equal objects will be factored: >>> t = (1, 2) >>> print dumps(((1, 2), (1, 2)), u=(1, 2)) (u, u) >>> print dumps((t, (1, 2)), u=(1, 2)) (u, u) For non hashable types, this is not the case unless the objects are actually the same object: >>> l = [1, 2] >>> print dumps((l, l), mylist=l) (mylist, mylist) >>> print dumps((l, [1, 2]), mylist=l) (mylist, [1, 2]) One last example: >>> a = 3 >>> b = [1, 2] >>> class C(object): pass ... >>> c = C() >>> c.x = a, b >>> b.append(c) >>> print dumps(c) sym0 = C(x=(3, [1, 2, sym0])) sym0 >>> c.y={a:b} >>> print dumps(c) sym0 = C(y={3: sym1}, x=(3, sym1)) sym1 = [1, 2, sym0] sym0 >>> print dumps(b) sym0 = [1, 2, C(y={3: sym0}, x=(3, sym0))] sym0 >>> print dumps(b, c=c) [1, 2, c] -- Arnaud

Arnaud Delobelle wrote:
Careful -- hashability is not necessarily the same thing as immutability. It's possible for an object to be hashable while still having mutable state, as long as the mutable state isn't included in the criteria for equality. But an application may still care about the identity of such objects. -- Greg
participants (3)
-
Arnaud Delobelle
-
Greg Ewing
-
Zaur Shibzoukhov