Various Small Python Helpers
I've been working lately with arkon on various projects related to diStorm. One of these projects involved writing a solid Python API around an existing C API. This C API uses a lot of flags as arguments and return values of functions.
Since I want my code to be easy to use in an interactive shell, I'd like to return something that's not just a number. The obvious solution is to use a Python Enum. There are many implementations going around, most of them equivalent. I've got the one I use. What I recently added though, is the SymbolInt:
class _SymbolInt(int):
def __str__(self):
return name
def __repr__(self):
return 'SymbolInt(%d, "%s")' % (value, name)
def __eq__(self, other):
if isinstance(other, str):
other = other.lower()
return int(self)==other or name.lower() == other
def __ne__(self, other):
return not self == other
return _SymbolInt(value)
Short, and very much to the point, this makes exploratory API's much more readable and usable. It is useful as a return value from enum functions as well.
Along with SymbolInt I wrote hexint:
def __str__(self):
return hex(self)[2:-1]
__repr__ = __str__
def __repr__(self):
return hex(self)[:-1]
This one makes program addresses readable.
Lastly, here's a little function that I found missing from itertools:
for obj,i in zip(iterable,xrange(num_items)):
yield obj
UPDATE: Don't use this head() function, use itertools.islice instead. Thanks go to Erez for pointing that out.
Tags: Programming, Python, Utility Functions
March 9th, 2008 at 4:16 pm
Neat @ first two.
The last one isn't missing (unless I misunderstood your intent): "enumerate" is a built-in since Python 2.4, I believe.
March 9th, 2008 at 4:53 pm
Yoni: You misunderstood my intent. Head takes the first num_items from iterable.
I'm piggy-backing on zip's behavior. zip always takes the shorter of the input sequences.
It also works for infinite sequences (such as itertools.count()).
Maybe I should have used itertools.izip instead though, to avoid generating the num_items of iterable at once.
And thanks!
March 13th, 2008 at 12:05 pm
Hi, two suggestions:
1) Replace hex(self)[2:-1] with '%x'%self. It's prettier.
Also, the 'L' postfix gets abandoned in Python 3.0 .
2) Your 'head' function is just a special case of 'itertools.islice' .
March 14th, 2008 at 6:50 am
1. You are correct. Using %x is more elegant, and will work in Python 3.
2. You are correct on this one as well. In fact, my implementation of head might cause a potential bug. This is because zip (and izip) leave long iterators in an uncertain state, by taking more elements than they should.
December 22nd, 2008 at 7:02 pm
[...] language. One hint for this is the many enum-like solutions you can find around the net. Some are simple and clean, but none provides all the features I [...]