Python: Inheriting a decorator overlay?

I work with a rather large base of OOP code, and I would like to add some trace / logging. The easiest way to do this is to introduce a decorator around certain methods on some base classes, but unfortunately decorators are not inherited.

I tried something like the following:

def trace(fn):
    def wrapper(instance, *args, **kwargs):
        result = fn(instance, *args, **kwargs)
        # trace logic...
        return result
    return wrapper

class BaseClass(object):
    def __init__(self, ...):
        ...
        self.__call__ = trace(self.__call__)  # line added to end of method

... and although the method __call__ completed (as can be seen from printing the instance information on the console), the function wrapperdoes not execute as expected.

I also briefly reviewed the use of the metaclass based on this answer , but it instantly breaks up other parts of the system that use introspection, so I find it worth going over.

__call__ , BaseClass?

+4
2

? , ? ( Python2.x):

class MyMeta(type):
    def __new__(mcl, name, bases, nmspc):
        if "__call__" in nmspc:
            nmspc["__call__"] = trace(nmspc["__call__"])
        return super(MyMeta, mcl).__new__(mcl, name, bases, nmspc)

class BaseClass(object):
    __metaclass__ = MyMeta

BaseClass __call__ .

, . BaseClass object, -, , MyMeta ( type).

+3

... . : Python

. . .

, - :

class BaseClass(object):
    __call__ = trace(object.__call__)
    def __init__(self, ...):
        ...

, .

edit: . , , - :

class BaseClass(object):
    @decorator
    __call__ = something

class SubClass(BaseClass):
    __call__ = something_else

... , BaseClass __call__, SubClass . -, (, , , python), . , : , , __call__ something decorator(something) ( ).

.

, , , ; , . factory.

, profile? , , .., , , ( ).

+3

All Articles