Steven D'Aprano <st***@REMOVETHIScyber.com.au> writes:
That looks great. Now, if only I understood mixins: what are they, and
what they are for, and in particular, how they differ from mere
subclassing.
I'm not sure what you mean by "mere subclassing" so maybe there is no
difference. Mixins are sort of a design pattern, not any whiz-tech
thing. The terminology comes from Flavors which was one of the early
multiple inheritance OOP systems. Flavors terminology was inspired by
ice cream: you could go to Tosci's and get plain ice cream, or ice
cream with your choice of various mix-ins like raisins, M&M's, heath
bar pieces, etc., which you could combine orthogonally. In Flavors
and in Python, mix-ins are superclasses that you inherit to turn on a
feature. The classic example is a Window class, with mixins for
scroll bars, title bars, pulldown menu, etc. So if you want a window
with a scroll bar, you'd say
class Window_with_scroll_bar(Window, Scrollbar): pass
and you'd get a class that understands the operations of both windows
and scroll bars. Flavors had automatic method combination that you
have to spell out manually in Python, making the scheme a little bit
less useful. But see SocketServer for a clever example of mixins to
implement concurrency in a TCP listener. The basic server class is
TCPServer and you inherit from ThreadingMixin to make a threading
server or ForkingMixin to make a forking server.
I guess what makes something a mix-in is that you normally don't
inherit from it directly. You inherit from some other class and the
mix-in is an "add-on" superclass that supplies some extra functionality.