Using Mix-ins with Python
Mix-in programming is a style of software development where units of functionality are created in a class and then mixed in with other classes. This might sound like simple inheritance at first, but a mix-in differs from a traditional class in one or more of the following ways. Often a mix-in is not the “primary” superclass of any given class, does not care what class it is used with, is used with many classes scattered throughout the class hierarchy and is introduced dynamically at runtime.
There are several reasons to use mix-ins: they extend existing classes in new areas without having to edit, maintain or merge with their source code; they keep project components (such as domain frameworks and interface frameworks) separate; they ease the creation of new classes by providing a grab bag of functionalities that can be combined as needed; and they overcome a limitation of subclassing, whereby a new subclass has no effect if objects of the original class are still being created in other parts of the software.
So while mix-ins are not a distinct technical feature of Python, the benefits of this technique are worth studying.
Python provides an ideal language for mix-in development because it supports multiple inheritance, supports full-dynamic binding and allows dynamic changes to classes. Before we dive into Python, let me admit that mix-ins are old hat. The first time I saw mix-in programming by that name was when reviewing the now-defunct Taligent Project, known for its Pink operating system and CommonPoint application framework. However, since C++ does not support language feature #2, full-dynamic binding, or language feature #3, dynamic changes at runtime, I'm not surprised that the approach didn't bring to fruition all its inventors had hoped for.
I have also seen another instance of mix-in programming under a different name. Objective-C has a nifty language feature called categories that allows you to add and replace methods of existing classes, even without access to their source code.
This is great for repairing existing system classes and extending their capabilities. Also, combined with an ability to load libraries dynamically, categories are quite effective in improving the structure of applications and reducing code.
The grapevine informs me that Symbolics' object-oriented Flavors system is most likely the earliest appearance of bona fide mix-ins. The designers were inspired by Steve's Ice Cream Parlor in Cambridge, Massachusetts where customers started with a basic flavor of ice cream (vanilla, chocolate, etc.) and added any combination of mix-ins (nuts, fudge, chocolate chips, etc.). In the Symbolics system, large, standalone classes were known as flavors while smaller helper classes designed for enhancing other classes were known as mix-ins. A reference can be found on the Web at www.kirkrader.com/examples/cpp/mixin.htm.
Having paid our respects to the dead (Taligent), nearly dead (Objective-C) and legendary (Symbolics), let's start digging into the features that make Python a great language for mix-in programming. For one, Python supports multiple inheritance. That is, in Python, a class can inherit more than one class:
class Server(Object, Configurable): pass
also, Python supports full-dynamic binding. When passing a message to an object such as:
obj.load(filename)Python will determine, entirely at runtime, what method to invoke, based on the name of the message and the class inheritance of obj. This behavior works as expected and is easy to remember. It continues to work even if the class inheritance or method definitions are altered at runtime.
One thing to keep in mind is the order of searching with regard to multiple inheritance. The search order goes from left to right through the base classes, and for any given base class, goes deep into its ancestor classes.
When you create mix-ins, keep in mind the potential for method names to clash. By creating distinct mix-ins with well-named methods you can generally avoid any surprises. Lastly, Python supports dynamic changes to the class hierarchy.
Most Python “things”, whether they are lists, dictionaries, classes or instances, have a set of accessible attributes. Python classes have an attribute named __bases__, which is a tuple of their base classes. Consistent with Python design, you can play with it at runtime. In the following session with the Python interactive interpreter seen in Listing 1, we create two classes and then later change the inheritance. Our person in Listing 1 isn't very friendly so let's change it. In fact, let's change all people so that we'll never have this problem again:
<<< Person.__bases__ += (Friendly,) <<< p.hello() Hello
The first statement above changes the base classes of Person. By using += (as opposed to =) we avoid accidentally removing existing base classes, especially if a future version of the code makes Person inherit from another class. Also, the funny looking expression, (Friendly,), specifies a tuple that would normally simply be enclosed in parenthesis. However, while Python readily recognizes <If“Courier”>(x,y)<I$f$> as a tuple of two elements, it recognizes <If“Courier”>(x)<I$f$> as a parenthesized expression. Appending the comma forces tuple recognition.
Fast/Flexible Linux OS Recovery
On Demand Now
In this live one-hour webinar, learn how to enhance your existing backup strategies for complete disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible full-system recovery solution for UNIX and Linux systems.
Join Linux Journal's Shawn Powers and David Huffman, President/CEO, Storix, Inc.
Free to Linux Journal readers.Register Now!
- Server Hardening
- BitTorrent Inc.'s Sync
- The Death of RoboVM
- EnterpriseDB's EDB Postgres Advanced Server and EDB Postgres Enterprise Manager
- The Humble Hacker?
- The US Government and Open-Source Software
- New Container Image Standard Promises More Portable Apps
- Open-Source Project Secretly Funded by CIA
- AdaCore's SPARK Pro
- ACI Worldwide's UP Retail Payments
In modern computer systems, privacy and security are mandatory. However, connections from the outside over public networks automatically imply risks. One easily available solution to avoid eavesdroppers’ attempts is SSH. But, its wide adoption during the past 21 years has made it a target for attackers, so hardening your system properly is a must.
Additionally, in highly regulated markets, you must comply with specific operational requirements, proving that you conform to standards and even that you have included new mandatory authentication methods, such as two-factor authentication. In this ebook, I discuss SSH and how to configure and manage it to guarantee that your network is safe, your data is secure and that you comply with relevant regulations.Get the Guide