title: pickling class method
body: <p>I have a class whose instances need to format output as instructed by the user. There's a default format, which can be overridden. I implemented it like this:</p>
  
  <pre><code>class A:
    def __init__(self, params):
      # ...
      # by default printing all float values as percentages with 2 decimals
      self.format_functions = {float: lambda x : '{:.2%}'.format(x)}
    def __str__(self):
      # uses self.format_functions to format output
      # ...
  
  a = A(params)
  print(a) # uses default output formatting
  
  # overriding default output formatting
  # float printed as percentages 3 decimal digits; bool printed as Y / N
  a.format_functions = {float : lambda x: '{:.3%}'.format(x),
                        bool : lambda x: 'Y' if x else 'N'}
  print(a)
  </code></pre>
  
  <p>Is it ok? Let me know if there is a better way to design this.</p>
  
  <p>Unfortunately, I need to pickle instances of this class. But only functions defined at the top level of the module can be pickled; <code>lambda</code> functions are unpicklable, so my <code>format_functions</code> instance attribute breaks the pickling.</p>
  
  <p>I tried rewriting this to use a class method instead of lambda functions, but still no luck for the same reason:</p>
  
  <pre><code>class A:
    @classmethod
    def default_float_format(cls, x):
      return '{:.2%}'.format(x)
    def __init__(self, params):
      # ...
      # by default printing all float values as percentages with 2 decimals
      self.format_functions = {float: self.default_float_format}
    def __str__(self):
      # uses self.format_functions to format output
      # ...
  
  a = A(params)
  pickle.dump(a) # Can't pickle &lt;class 'method'&gt;: attribute lookup builtins.method failed
  </code></pre>
  
  <p>Note that pickling here doesn't work even if I don't override the defaults; just the fact that I assigned <code>self.format_functions = {float : self.default_float_format}</code> breaks it.</p>
  
  <p>What to do? I'd rather not pollute the namespace and break encapsulation by defining <code>default_float_format</code> at the module level.</p>
  
  <p>Incidentally, why in the world does <code>pickle</code> create this restriction? It certainly feels like a gratuitous and substantial pain to the end user.</p>