Python - print method name when calling class methods

I need to perform certain operations every time a method of a certain class is called (e.g. register a method name). How can this be achieved in Python in general?

+5
source share
4 answers

Decorate the attributes to be called from the metaclass:

from functools import wraps def _log_method(val): @wraps(val) def wrapper(*a, **ka): print(val.__name__, 'is called') val(*a, **ka) return wrapper class LogMethodCalls(type): def __new__(cls, cls_name, bases, attrs): for name, attr in attrs.items(): if callable(attr): attrs[name] = _log_method(attr) return type.__new__(cls, cls_name, bases, attrs) class Foo(metaclass=LogMethodCalls): def my_method(self): pass Foo().my_method() # my_method is called 

Warning This code only works for methods, methods that were decorated with @classmethod or @staticmethod will not be registered (because the classmethod and staticmethod not staticmethod - they are simply descriptors without data).


The following actions are used for class methods and static methods:

 from functools import wraps def _log_method(val): @wraps(val) def wrapper(*a, **ka): print('calling', val.__name__) val(*a, **ka) return wrapper class LogMethodCalls(type): def __new__(cls, cls_name, bases, attrs): for name, attr in attrs.items(): if callable(attr): attrs[name] = _log_method(attr) elif isinstance(attr, (classmethod, staticmethod)): attrs[name] = type(attr)(_log_method(attr.__func__)) return type.__new__(cls, cls_name, bases, attrs) class Foo(metaclass=LogMethodCalls): def my_instance_method(self): pass @classmethod def my_class_method(cls): pass @staticmethod def my_static_method(): pass Foo().my_instance_method() # calling my_instance_method Foo.my_class_method() # calling my_class_method Foo.my_static_method() # calling my_static_method 

They have __func__ attributes that we can decorate.


Please note that you will need to use

 class Foo(object): __metaclass__ = LogMethodCalls 

in Python 2.

+6
source

Taken from this answer . You can use the inspect module to look at the stack for the function name to create a simple logging function. It seems like a khachka, but I suppose it answers the question.

 import inspect def log_call(): print(inspect.stack()[1][3]) def my_func(): log_call() # do stuff my_func() 

my_func open.

+3
source

You can implement a decorator :

 from functools import wraps def print_function_name(function): @wraps(function) def do_it(): print function.__name__ function() return do_it 

Using:

 class MyClass(object): @print_function_name def some_function(self): pass 

For instance:

 >>> my_object = MyClass() >>> my_object.some_function() some_function 

Using functools.wraps ensures that the function retains its documentation and name instead of becoming do_it .

+2
source

Taken from fooobar.com/questions/342276 / ... :
The following object class method is called each time the object attribute is accessed, including method calls:

  __get_attribute__

Therefore, I suggest overriding it by simply adding a call to the logging function inside.
See fooobar.com/questions/342276 / ... (skip to the last answer) for sample code.

0
source

All Articles