Я пишу некоторый код, который пересекает структуру, которая может иметь циклические ссылки.Вместо того, чтобы явно выполнять проверки в начале рекурсивных функций, я подумал, что создам декоратор, который не позволяет вызывать функцию более одного раза с одними и теми же аргументами.
Ниже приведено описаниес.Как написано, это попытается перебрать Nontype и вызвать исключение.Я знаю, что мог бы это исправить, вернув, скажем, пустой список, но я хотел быть более элегантным.Есть ли способ определить из декоратора, является ли декорируемая функция генератором или нет?Таким образом, я мог бы условно повысить StopIteration, если это генератор, или просто вернуть None в противном случае.
previous = set()
def NO_DUPLICATE_CALLS(func):
def wrapped(*args, **kwargs):
if args in previous:
print 'skipping previous call to %s with args %s %s' % (func.func_name, repr(args), repr(kwargs))
return
else:
ret = func(*args, **kwargs)
previous.add(args)
return ret
return wrapped
@NO_DUPLICATE_CALLS
def foo(x):
for y in x:
yield y
for f in foo('Hello'):
print f
for f in foo('Hello'):
print f