title: Python Class Based Decorator with parameters that can decorate a method or a function
body: <p>I've seen many examples of Python decorators that are:</p>
  
  <ul>
  <li>function style decorators (wrapping a function)</li>
  <li>class style decorators (implementing <code>__init__</code>, <code>__get__</code>, and <code>__call__</code>)</li>
  <li>decorators which do not take arguments</li>
  <li>decorators which take arguments</li>
  <li>decorators which are "method friendly" (ie can decorate a method in a class)</li>
  <li>decorators which are "function friendly" (can decorate a plain function</li>
  <li>decorators that can decorate both methods and functions</li>
  </ul>
  
  <p>But I've never seen a single example which can do all of the above, and I'm having trouble synthesizing from various answers to specific questions (such as <a href="https://stackoverflow.com/questions/1288498/using-the-same-decorator-with-arguments-with-functions-and-methods">this one</a>, <a href="https://stackoverflow.com/questions/2365701/decorating-python-class-methods-how-do-i-pass-the-instance-to-the-decorator">this one</a>, or <a href="https://stackoverflow.com/questions/739654/understanding-python-decorators">this one (which has one of the best answers I've ever seen on SO)</a>), how to combine all of the above.</p>
  
  <p>What I want is a <em><strong>class-based</strong></em> decorator which can decorate <em><strong>either a method or a function</strong></em>, and <em><strong>that takes at least one additional parameter</strong></em>.  Ie so that the following would work:</p>
  
  <pre><code>class MyDecorator(object):
      def __init__(self, fn, argument):
          self.fn = fn
          self.arg = argument
  
      def __get__(self, ....):
          # voodoo magic for handling distinction between method and function here
  
      def __call__(self, *args, *kwargs):
          print "In my decorator before call, with arg %s" % self.arg
          self.fn(*args, **kwargs)
          print "In my decorator after call, with arg %s" % self.arg
  
  
  class Foo(object):
      @MyDecorator("foo baby!")
      def bar(self):
          print "in bar!"
  
  
  @MyDecorator("some other func!")
  def some_other_function():
      print "in some other function!"
  
  some_other_function()
  Foo().bar()
  </code></pre>
  
  <p>And I would expect to see:</p>
  
  <pre><code>In my decorator before call, with arg some other func!
  in some other function!
  In my decorator after call, with arg some other func!
  In my decorator before call, with arg foo baby!
  in bar!
  In my decorator after call, with arg foo baby!
  </code></pre>
  
  <p>Edit: if it matters, I'm using Python 2.7.</p>