[Python-Dev] Christmas Wishlist (original) (raw)
Raymond Hettinger raymond.hettinger at verizon.net
Sun Dec 14 16:31:09 EST 2003
- Previous message: [Python-Dev] Python-checkins list
- Next message: [Python-Dev] Re: Christmas Wishlist
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I. eval() to accept custom mapping arguments for globals and locals. This makes it possible to write a smart getitem method for applications like spreadsheets or case-insensitive evaluation.
class LowerCaseDict(dict): def getitem(self, key): return dict.getitem(self, key.lower())
print eval(rawinput('Okay kids, type in an expression:', LowerCaseDict(globals()))
Okay kids, type in an expression: HeX(20) 0x14
class SpreadSheet: _cells = {} def setitem(self, key, formula): self._cells[key] = formula def getitem(self, key): return eval(self._cells[key], self)
ss = SpreadSheet() ss['a1'] = '5' ss['a2'] = 'a1*5' ss['a2']
While this seems like a minor feature request, it presents amazing opportunities to avoid writing lexers, parsers, interpreters by transferring the work to the python interpreter. Writing little languages like the spreadsheet class becomes almost trivial.
II. Timer.timeit to take an optional context argument.
from timeit import Timer a = 20 def f(x): ... return x + 20
Timer('f(10)', env=globals()).timeit() 1.234
The idea is to make it much easier to time functions or parts of existing modules. Having to write-out the definition in a long setup string is cumbersome and interferes with syntax highlighting. To instrument modules with timeit, the timer setup string currently has to re-import the whole module -- passing in an execution environment is much more straight-forward. And, as the example shows, passing in globals() makes it easier to experiment with timings using the interpreter.
III. enumerate to take an optional argument:
enumerate([firstnumber=0,] iterable)
The idea is to make enumerate() a complete solution to the loop counter problem:
for lineno, line in enumerate(1, file('hist.log')): print lineno, line
IV. list.sorted() to become just sorted(). All of the common use cases read better without the "list." prefix:
topscores = sorted(team.score for team in teams)[:10] for k, v in sorted(mydict.iteritems()): . . . byAge = operator.itemgetter('age') for age, students in groupby(sorted(studentbody, key=byAge), key=byAge): ... print "Age group:", age ... for student in students: ... print '...', student.name, student.address
Also, this Christmas wish cures the weirdness that comes from the classmethod approach:
[3,2,1].sorted('cbs') ['b', 'c', 's'].
While I worry about the total number of builtins, opposing them on principle is a recipe for putting tools where they don't belong. IMO, making list.sorted() a class method was a clumsy way of avoiding the obvious solution and left it smelling a bit hackish.
Raymond Hettinger
- Previous message: [Python-Dev] Python-checkins list
- Next message: [Python-Dev] Re: Christmas Wishlist
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]