Есть три очевидных проблемы с вашим кодом на самом деле.
Первая - это TypeError - которую легко решить FWIW: поскольку сообщение об ошибке (повышается с помощью setattr()
состояний), имя атрибута должно быть string, а не 'instancemethod' ". И вы действительно пытаетесь использовать f
(сам метод) вместо method_name
. Здесь вам, конечно, нужно:
setattr(c, method_name, SafeCall(f))
Вторая проблема в том, что ваш SafeCall «декоратор» НЕ является декоратором. Декоратор (ну, по крайней мере, тот тип декоратора, который вы хотите здесь по крайней мере) возвращает функцию, которая оборачивает исходную, ваша текущая реализация просто вызывает исходную функцию. На самом деле, это почти то, что на самом деле должен возвращать SafeCall
. Пример правильного декоратора:
def decorator(func):
def wrapper(*args, **kw):
print("before calling {}".format(func))
result = func(*args, **kw)
print("after calling {}".format(func))
return result
return wrapper
И, наконец, третья очевидная проблема здесь:
except:
print 'exception caught'
return None
Вы, конечно, не хотите этого. Этот
1 / будет перехватывать абсолютно все (включая SysExit
, то есть то, что Python поднимает при вызовах sys.exit()
и StopIteration
, как сигналы итераторов они исчерпаны),
2 / откажитесь от всей очень полезной информации об отладке - сделав невозможной диагностику того, что на самом деле пошло не так
3 / верните что-то, что может быть просто непригодным для использования, так что вы получите чтобы проверить возвращаемое значение каждого вызова метода, и так как вы не будете знать, что пошло не так, вы не сможете решить проблему иначе, чем печатать «упс, что-то пошло не так, но не спрашивайте меня, что ни где, ни почему »и выход из программы, что определенно не лучше, чем позволить распространению исключения - программа выполнит sh в обоих случаях, но, по крайней мере, если вы оставите это исключение, у вас будут некоторые намеки на причину проблемы.
4 / или, что еще хуже, возвращает допустимое возвращаемое значение для метода (да, довольно много методов предназначены для изменения состояния и возврата None
), так что вы даже не узнаете, что что-то пошло не так и счастливо продолжить выполнение - это верный способ получить неверный результат и поврежденные данные.
5 / не говоря уже о том, что методы, которые вы декорируете таким образом, очень вероятно вызывают друг друга и используют (ожидаемые) исключения внутренне (с правильной обработкой исключений), так что вы на самом деле внесение ошибок в работающую (или в основном работающую) библиотеку.
IOW, это, вероятно, худший антипаттерн, о котором вы когда-либо могли подумать ...