Book Excerpt: The Python Standard Library by Example
Under Python 2, classes can define a __cmp__() method that returns -1, 0, or 1 based on whether the object is less than, equal to, or greater than the item being compared. Python 2.1 introduces the rich comparison methods API (__lt__(), __le__(), __eq__(), __ne__(), __gt__(), and __ge__()), which perform a single comparison operation and return a Boolean value. Python 3 deprecated __cmp__() in favor of these new methods, so functools provides tools to make it easier to write Python 2 classes that comply with the new comparison requirements in Python 3.
The rich comparison API is designed to allow classes with complex comparisons to implement each test in the most efficient way possible. However, for classes where comparison is relatively simple, there is no point in manually creating each of the rich comparison methods. The total_ordering() class decorator takes a class that provides some of the methods and adds the rest of them.
import functools import inspect from pprint import pprint @functools.total_ordering class MyObject(object): def __init__(self, val): self.val = val def __eq__(self, other): print ’ testing __eq__(%s, %s)’ % (self.val, other.val) return self.val == other.val def __gt__(self, other): print ’ testing __gt__(%s, %s)’ % (self.val, other.val) return self.val > other.val print ’Methods:\n’ pprint(inspect.getmembers(MyObject, inspect.ismethod)) a = MyObject(1) b = MyObject(2) print ’\nComparisons:’ for expr in [ ’a < b’, ’a <= b’, ’a == b’, ’a >= b’, ’a > b’ ]: print ’\n%-6s:’ % expr result = eval(expr) print ’ result of %s: <%s’ % (expr, result)
The class must provide implementation of __eq__() and one other rich comparison method. The decorator adds implementations of the rest of the methods that work by using the comparisons provided.
$ python functools_total_ordering.py Methods: [(’__eq__’, <unbound method MyObject.__eq__>), (’__ge__’, <unbound method MyObject.__ge__>), (’__gt__’, <unbound method MyObject.__gt__>), (’__init__’, <unbound method MyObject.__init__>), (’__le__’, <unbound method MyObject.__le__>), (’__lt__’, <unbound method MyObject.__lt__>)] Comparisons: a < b: testing __gt__(2, 1) result of a < b: True a <= b: testing __gt__(1, 2) result of a <= b: True a == b: testing __eq__(1, 2) result of a == b: False a >= b: testing __gt__(2, 1) result of a >= b: False a > b: testing __gt__(1, 2) result of a > b: False
Since old-style comparison functions are deprecated in Python 3, the cmp argument to functions like sort() is also no longer supported. Python 2 programs that use comparison functions can use cmp_to_key() to convert them to a function that returns a collation key, which is used to determine the position in the final sequence.
import functools class MyObject(object): def __init__(self, val): self.val = val def __str__(self): return ’MyObject(%s)’ % self.val def compare_obj(a, b): """Old-style comparison function. """ print ’comparing %s and %s’ % (a, b) return cmp(a.val, b.val) # Make a key function using cmp_to_key() get_key = functools.cmp_to_key(compare_obj) def get_key_wrapper(o): """Wrapper function for get_key to allow for print statements. """ new_key = get_key(o) print ’key_wrapper(%s) -> %s’ % (o, new_key) return new_key objs = [ MyObject(x) for x in xrange(5, 0, -1) ] for o in sorted(objs, key=get_key_wrapper): print o
Normally, cmp_to_key() would be used directly, but in this example, an extra wrapper function is introduced to print out more information as the key function is being called.
The output shows that sorted() starts by calling get_key_wrapper() for each item in the sequence to produce a key. The keys returned by cmp_to_key() are instances of a class defined in functools that implements the rich comparison API using the old-style comparison function passed in. After all keys are created, the sequence is sorted by comparing the keys.
$ python functools_cmp_to_key.py key_wrapper(MyObject(5)) -> <functools.K object at 0x100da2a50> key_wrapper(MyObject(4)) -> <functools.K object at 0x100da2a90> key_wrapper(MyObject(3)) -> <functools.K object at 0x100da2ad0> key_wrapper(MyObject(2)) -> <functools.K object at 0x100da2b10> key_wrapper(MyObject(1)) -> <functools.K object at 0x100da2b50> comparing MyObject(4) and MyObject(5) comparing MyObject(3) and MyObject(4) comparing MyObject(2) and MyObject(3) comparing MyObject(1) and MyObject(2) MyObject(1) MyObject(2) MyObject(3) MyObject(4) MyObject(5)
functools (http://docs.python.org/library/functools.html) The standard library documentation for this module.
Rich comparison methods (http://docs.python.org/reference/datamodel.html# object.__lt__) Description of the rich comparison methods from the Python Reference Guide.
inspect (page 1200) Introspection API for live objects.
© Copyright Pearson Education. All rights reserved.
Excerpt from Python Standard Library by Example, The.
|By Doug Hellmann
Published by Addison-Wesley Professional
This excerpt is from the book, ‘The Python Standard Library by Example’ by Doug Hellmann, published by Pearson/Addison-Wesley Professional, June 2011, ISBN 0321767349, Copyright 2011 Pearson Education, Inc. For more info please visit www.informit.com/title/0321767349
Practical Task Scheduling Deployment
One of the best things about the UNIX environment (aside from being stable and efficient) is the vast array of software tools available to help you do your job. Traditionally, a UNIX tool does only one thing, but does that one thing very well. For example, grep is very easy to use and can search vast amounts of data quickly. The find tool can find a particular file or files based on all kinds of criteria. It's pretty easy to string these tools together to build even more powerful tools, such as a tool that finds all of the .log files in the /home directory and searches each one for a particular entry. This erector-set mentality allows UNIX system administrators to seem to always have the right tool for the job.
Cron traditionally has been considered another such a tool for job scheduling, but is it enough? This webinar considers that very question. The first part builds on a previous Geek Guide, Beyond Cron, and briefly describes how to know when it might be time to consider upgrading your job scheduling infrastructure. The second part presents an actual planning and implementation framework.
Join Linux Journal's Mike Diehl and Pat Cameron of Help Systems.
Free to Linux Journal readers.View Now!
|The Firebird Project's Firebird Relational Database||Jul 29, 2016|
|Stunnel Security for Oracle||Jul 28, 2016|
|SUSE LLC's SUSE Manager||Jul 21, 2016|
|My +1 Sword of Productivity||Jul 20, 2016|
|Non-Linux FOSS: Caffeine!||Jul 19, 2016|
|Murat Yener and Onur Dundar's Expert Android Studio (Wrox)||Jul 18, 2016|
- The Firebird Project's Firebird Relational Database
- Stunnel Security for Oracle
- My +1 Sword of Productivity
- Non-Linux FOSS: Caffeine!
- SUSE LLC's SUSE Manager
- Managing Linux Using Puppet
- Murat Yener and Onur Dundar's Expert Android Studio (Wrox)
- Parsing an RSS News Feed with a Bash Script
- Google's SwiftShader Released
- Doing for User Space What We Did for Kernel Space
With all the industry talk about the benefits of Linux on Power and all the performance advantages offered by its open architecture, you may be considering a move in that direction. If you are thinking about analytics, big data and cloud computing, you would be right to evaluate Power. The idea of using commodity x86 hardware and replacing it every three years is an outdated cost model. It doesn’t consider the total cost of ownership, and it doesn’t consider the advantage of real processing power, high-availability and multithreading like a demon.
This ebook takes a look at some of the practical applications of the Linux on Power platform and ways you might bring all the performance power of this open architecture to bear for your organization. There are no smoke and mirrors here—just hard, cold, empirical evidence provided by independent sources. I also consider some innovative ways Linux on Power will be used in the future.Get the Guide