декоратор Python для функции ИЛИ класса

Просто запрашиваю мнение о том, является ли нижеследующее разумным или есть лучший подход. В основном мне нужен декоратор, который будет применяться к функции или классу, реализующему __call__.

Вы могли бы просто иметь обычный декоратор и явно украсить __call__, но тогда декоратор спрятан внутри определения класса и менее очевиден. Возможно, мне не хватает более простого решения.

import types
from functools import wraps

class dec:
    """ Decorates either a class that implements __call__ 
        or a function directly.
    """
    def __init__(self, foo):
        self._foo = foo

    def __call__(self, target):
        wraps_class = isinstance(target, types.ClassType)
        if wraps_class:
            fun = target.__call__
        else:
            fun = target

        @wraps(fun)
        def bar(*args, **kwds):
            val = args[1] if wraps_class else args[0]
            print self._foo, val
            return fun(*args, **kwds)
        if wraps_class:
            target.__call__ = bar
            return target
        else:
            return bar

@dec('A')
class a:
    # you could decorate here, but it seems a bit hidden
    def __call__(self, val):
        print "passed to a:", val

@dec('B')
def b(val):
    print "passed to b:", val

a()(11)
b(22)
5
задан Michael J. Barber 15 February 2012 в 14:59
поделиться