I was lucky to get a seat (and dinner) at the standing room-only presentation by Alex Martelli tonight. The talk, which was a repeat of his PyCon talk, called Python Design Patterns and OOP, was hosted by Google. His theme throughout the talk was that of delegation in OOP (object oriented programming), and who gets delegated what when programming. I'll provide an overview of what I gleaned. Design patterns referenced here should be available in the online Python Cookbook or the dead tree version which was authored in part by Martelli.
Hold vs Wrap
Holding and wrapping both hinvolve encapsulating "sub-objects". They are distinguished that in the former the api intends for the user to call methods on and access the sub-objects directly, while the latter holds the sub-object in a private name and delegates calls to it through methods. Use wrapping as it allows for flexibility in swapping out the implementation as necessary. A good rule of thumb is if you have more than one dot (period) when accessing the encapsulating class, you are probably using "holding" which leaves the user hard- wired into an implementation.
Wrap vs Inheritance
Wrapping has an advantage over inheritance in that you can hide and restrict access to members. (Don't provide the user with too much power if it's not needed). Most oop programmers think that polymorphism is achieved only through inheritance, yet this is not the case for python. Because python uses "duck typing" (if it quacks like a duck, it's a duck, if it floats...), and polymorphism is based on signatures not classes, one is able to wrap and still achieve polymorphism.
Classes in python may delegate implementation within themselves by separating "hook" methods and "organizing" methods. An example Alex gave is the Queue class which has a "put" method that takes care of thread sychronization while accessing the queue (an organization method). Within the put method there is a call to "_put" which is a hook method. One may subclass or override the _put method if they want to control the storage of the item being "putted" but not worry about the threading issues.
The UserDict class also allows for self delegation as the user must implement the "hook" methods, but have the basic skeleton for a class, and don't have to implement that plumbing.
Other Design Patterns
Alex discussed a few more patterns, namely Strategy (useful to use in place of a flag when implementing different levels of logging/debugging) and Null Object (replace the "if x is None:"). To cap it all off, Alex presented the difference between Singleton and Monostate (borg).
He lamented that Guido was not present to be convinced of the Borg's usefulness. (See the link above where Alex has commented about the differences between a singleton and the borg and why you probably want to use borg). All in all it was a well presented talk of pretty sound pythonic programming practices. I'm looking forward to his "black magic" talk in two months.