Питон - статьи



             

Листинг 6. Мультиметоды для расширения возможностей


# Base rules (stipulate combination is order independent) class Circle(Shape): pass class Square(Shape): pass def circle_with_square(circle, square): ... def circle_with_circle(circle, circle): ... def square_with_square(square, square): ... combine = Dispatch() combine.add_rule((Circle, Square), circle_with_square) combine.add_rule((Circle, Circle), circle_with_circle) combine.add_rule((Square, Square), square_with_square) combine.add_rule((Square, Circle), lambda s,c: circle_with_square(c,s)) # Enhancing base with triangle shape class Triangle(Shape): pass def triangle_with_triangle(triangle, triangle): ... def triangle_with_circle(triangle, circle): ... def triangle_with_square(triangle, square): ... combine.add_rule((Triangle,Triangle), triangle_with_triangle) combine.add_rule((Triangle,Circle), triangle_with_circle) combine.add_rule((Triangle,Square), triangle_with_square) combine.add_rule((Circle,Triangle), lambda c,t: triangle_with_circle(t,c)) combine.add_rule((Square,Triangle), lambda s,t: triangle_with_square(t,s)) # Use the rules in application c, t, s = Circle(...), Triangle(...), Square(...) newshape1 = combine(c, t)[0] newshape2 = combine(s, c)[0] # discover 'x' of unknown type, then combine with 't' newshape3 = combine(t, x)[0]

Определение новых правил (и поддержка функций/методов) в значительной степени эквивалентны. Но огромное преимущество стиля множественной диспетчеризации - это цельность, с помощью которой вы комбинировать фигуры неизвестных типов. Вместо того, чтобы возвращаться к явным (и длинным) условным блокам, определения правил автоматически решают эти вопросы. Что еще лучше, все комбинирование выполняется одним вызовом combine(), а не с помощью "зверинца" из разных комбинирующих методов.




Содержание  Назад  Вперед