Лучший способ записывать вызовы методов в Python?
Мы можем закодировать какой-то декодер ведения журнала для вызовов эхо-функций/методов, например:
def log(fn):
...
@log
def foo():
...
class Foo(object):
@log
def foo(self):
...
@log
def bar(self, a, b):
...
@log
def foobar(self, x, y, z):
...
Но что, если нам нравится записывать вызовы методов, не помещая это много @log перед каждым определением meth? Есть ли способ просто поставить один декоратор над определением класса, чтобы все его вызовы методов были украшены/записаны? Или есть некоторые другие интересные и интересные способы сделать это вместо декоратора?
Ответы
Ответ 1
См. Прикрепление декоратора ко всем функциям класса
Однако, как указывает принятый ответ на этот вопрос, обычно это не очень хорошая идея.
Если вы решите перейти на аспект ориентированный маршрут программирования, я предлагаю начать здесь: Любая библиотека поддержки AOP для Python?
Ответ 2
Это может быть излишним, но есть функция функции трассировки, которая сообщит вам о большой активности в вашей программе:
import sys
def trace(frame, event, arg):
if event == "call":
filename = frame.f_code.co_filename
if filename == "path/to/myfile.py":
lineno = frame.f_lineno
# Here I'm printing the file and line number,
# but you can examine the frame, locals, etc too.
print "%s @ %s" % (filename, lineno)
return trace
sys.settrace(trace)
call_my_function()
sys.settrace(None)
Ответ 3
Я не уверен, что ваш вариант использования для этого, но в целом я бы подумал больше о том, что именно проблема, которую вы пытаетесь решить.
Итак, вот пример, который может сделать то, что вы хотите, но без декоратора:
#!/usr/bin/env python
import inspect
class Foo(object):
def foo(self):
pass
def bar(self, a, b):
pass
def foobar(self, x, y, z):
pass
def __getattribute__(self, name):
returned = object.__getattribute__(self, name)
if inspect.isfunction(returned) or inspect.ismethod(returned):
print 'called ', returned.__name__
return returned
if __name__ == '__main__':
a = Foo()
a.foo()
a.bar(1, 2)
a.foobar(1, 2, 3)
Вывод:
called foo
called bar
called foobar
Ответ 4
Ну, если вы не хотите явно украшать все свои функции, вы можете получить все функции/методы данного модуля и применить свой декоратор автоматически. не самая простая вещь, но не невозможная в python:)
Вы также можете попробовать аспектно-ориентированную структуру программирования.
my2c