title: Python decorator with multiprocessing fails
body: <p>I would like to use a decorator on a function that I will subsequently pass to a multiprocessing pool. However, the code fails with "PicklingError: Can't pickle : attribute lookup <code>__builtin__</code>.function failed". I don't quite see why it fails here. I feel certain that it's something simple, but I can't find it. Below is a minimal "working" example. I thought that using the <code>functools</code> function would be enough to let this work. </p>
  
  <p>If I comment out the function decoration, it works without an issue. What is it about <code>multiprocessing</code> that I'm misunderstanding here? Is there any way to make this work?</p>
  
  <p><strong>Edit</strong>: After adding both a callable class decorator <em>and</em> a function decorator, it turns out that the function decorator <em>works as expected</em>. The callable class decorator continues to fail. What is it about the callable class version that keeps it from being pickled?</p>
  
  <pre><code>import random
  import multiprocessing
  import functools
  
  class my_decorator_class(object):
      def __init__(self, target):
          self.target = target
          try:
              functools.update_wrapper(self, target)
          except:
              pass
  
      def __call__(self, elements):
          f = []
          for element in elements:
              f.append(self.target([element])[0])
          return f
  
  def my_decorator_function(target):
      @functools.wraps(target)
      def inner(elements):
          f = []
          for element in elements:
              f.append(target([element])[0])
          return f
      return inner
  
  @my_decorator_function
  def my_func(elements):
      f = []
      for element in elements:
          f.append(sum(element))
      return f
  
  if __name__ == '__main__':
      elements = [[random.randint(0, 9) for _ in range(5)] for _ in range(10)]
      pool = multiprocessing.Pool(processes=4)
      results = [pool.apply_async(my_func, ([e],)) for e in elements]
      pool.close()
      f = [r.get()[0] for r in results]
      print(f)
  </code></pre>