protocol.py

Send to Kindle
home » snippets » python » pickle » protocol.py


#!/usr/bin/env python2_6
import cPickle as pickle

if __name__ == "__main__":
  import ck.interactive
  ck.interactive.initialize(session_name="learn")

class A(object):
  def __new__(cls, *args):
    print "In A::__new__(%s, args=%s)" % (cls, args)
    return super(A, cls).__new__(cls)

  def __init__(self, x, y):
    print "In A::__init__(%s, %s, %s)" % (self, x, y)
    self.x, self.y = x, y

  def __getnewargs__(self):
    print "In A::__getnewargs__(%s):" % (self,)
    return (self.x, self.y)

if __name__ == "__main__":
  # In this example, we learn that defining __getnewargs__ means
  # - it will be called when pickling (an protocol 2 is used.)
  # - __new__ will be called with those args on unpickling
  # - BUT __init__ will not be called following the __new__ on unpickling (as it is during construction.)

  a = A(2, 3)  # __new__ AND __init__ are called.
  data = pickle.dumps(a, 2) # use protocol 2 - __getnewargs__ requires it.
  a2 = pickle.loads(data)  # __new__ is called, but __init__ is not called.
  assert a2.x == a.x and a2.y == a.y
  print "END of example\n\n"


class A(object):
  def __new__(cls, *args):
    print "In A::__new__(%s, args=%s)" % (cls, args)
    return super(A, cls).__new__(cls)

  def __init__(self, x, y):
    print "In A::__init__(%s, %s, %s)" % (self, x, y)
    self.x, self.y = x, y

  def __getnewargs__(self):
    print "In A::__getnewargs__(%s):" % (self,)
    return (self.x, self.y)

  def __setstate__(self, state):
    print "In A::__setstate__(%s, %s):" % (self, state)
    # Note:  Turns out object has no __setstate__ so we can't call the super method.
    # super(A, self).__setstate__(state)
    self.__dict__.update(state)


if __name__ == "__main__":
  # Same as befire but also defining __setstate__
  a = A(2, 3)  # __new__ AND __init__ are called.
  data = pickle.dumps(a, 2) # use protocol 2 - __getnewargs__ requires it.
  a2 = pickle.loads(data)  # __new__ is called, but __init__ is not called.
  assert a2.x == a.x and a2.y == a.y

  print "END of example\n\n"


if __name__ == "__main__":
  ck.interactive.interact(local=globals())