Getting Rich with Comparison Methods10:15 AM - 11:00 AM on August 16, 2014, Room 704
- Audience level:
Matt's obsession with Python's rich comparison methods started about 6 years ago with a gnarly bug and some bad assumptions. A few long nights and a lot of reading later, the docs corrected my assumption:
There are no implied relationships among the comparison operators. The truth of x==y does not imply that x!=y is false.
Mind == blown and mind != blown. In Getting Rich with Comparison Methods we'll start by learning how to avoid common and costly bugs in your rich comparison methods, learn a bit about which methods are executed in comparisons and why, and then go beyond symmetrical comparisons exploring some of the ways we can take full advantage of asymmetrical comparison methods.
"Getting Rich with Comparison Methods" starts with what most engineers are trying to do when they first read the data model documentation for rich comparison methods, make comparisons function "as expected", returning truthy and falsey values. A common case is an object with an id attribute, and rather than: self == other being translated into: self is other, you'd prefer it to turn into self.id == other.id. Conversely you'd like self != to translate to: self.id != other.id, and you might go so far as to define '>', '>=', '<' and '<=' too. Straight-forward as this seems there are some pitfalls to avoid, and (of course) some standard library goodies that make avoiding these pitfalls as easy as decorating your class.
Once you've handled this basic use-case, you'll eventually compare your object to an object of a different type, and you'll start to wonder exactly how Python chooses the rich comparison method of record. Grasping how order and inheritence of objects in a comparison play into the resolution of the rich comparison method will allow you to write more resiliant c ode, and will lead you to understand the importance of extensive testing whenever rich comparison methods are involved.
Once again, the standard library saves us, this time with the operator module providing us with the ability to write simple (and non-ugly) tests for our rich comparison enabled classes. The final step in our rich comparison journey is to begin to understand how to harness the power of asymmetrical and non-boolean comparisons to build powerful and expressive fu nctionality (like the kind found in SQLALchemy, just to name one).
By the time you leave "Getting Rich with Comparison Methods" you should be comfortable using rich comparison methods to solve a variety of problems, you should be able to write elegant tests for your comparison method code, and you'll know what they say about assumptions.