Python Class Based Decorator con parámetros que pueden decorar un método o una función

He visto muchos ejemplos de decoradores de Python que son:

decoradores de estilo de función (envolviendo una función)ecoradores de estilo @class (implementando__init__, __get__ y__call__) decoradores que no toman argumentos decoradores que toman argumentosdecoradores que son "amigables con los métodos" (es decir, pueden decorar un método en una clase)decoradores que son "amigables con la función" (pueden decorar una función simple decoradores que pueden decorar métodos y funciones

Pero nunca he visto un solo ejemplo que pueda hacer todo lo anterior, y tengo problemas para sintetizar a partir de varias respuestas a preguntas específicas (comoést, ést oesta (que tiene una de las mejores respuestas que he visto en SO)), cómo combinar todo lo anterior.

Lo que quiero es un basado en clase decorador que puede decorar ya sea un método o una función yque toma al menos un parámetro adicional. Es decir, para que funcione lo siguiente:

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()

Y esperaría ver:

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!

Edit: si es importante, estoy usando Python 2.7.

Respuestas a la pregunta(6)

Su respuesta a la pregunta