Я занимаюсь определением столкновений и очень хотел бы использовать одну и ту же функцию в двух разных контекстах.В одном контексте я хотел бы, чтобы это было что-то вроде
def detect_collisions(item, others):
return any(collides(item, other) for other in others)
, а в другом я хотел бы, чтобы оно было
def get_collisions(item, others):
return [other for other in others if collides(item, other)]
Я действительно ненавижу идею написания двух функцийВот.Простое сохранение их имен - это один поворот, а усложнение интерфейса для обнаружения столкновений - другое.поэтому я подумал:
def peek(gen):
try:
first = next(gen)
except StopIteration:
return False
else:
return it.chain((first,), gen)
def get_collisions(item, others):
get_collisions.all = peek(other for other in others if collides(item, other))
return get_collisions.all
Теперь, когда я просто хочу сделать проверку, я могу сказать:
if get_collisions(item, others):
# aw snap
или
if not get_collisions(item, others):
# w00t
и вВ другом контексте, где я действительно хочу их изучить, я могу сделать:
if get_collisions(item, others):
for collision in get_collisions.all:
# fix it
, и в обоих случаях я не выполняю больше обработки, чем нужно.
Я понимаю, чтоэто больше кода, чем первые две функции, но он также имеет преимущество:
Сохранение моего интерфейса для обнаружения столкновений в виде дерева с узлом на верхнем уровне вместо среднегоуровень.Это кажется проще.
Подключить себя к удобной функции быстрого просмотра.Если я использую это в другой раз, то на самом деле я пишу меньше кода.(В ответ на YAGNI, если он у меня будет, я буду)
Итак.Если бы вы были маньяком-убийцей из пословиц, который знает, где я живу, я бы ожидал от вас визита, если бы написал вышеприведенный код?Если да, как бы вы подошли к этой ситуации?