""" Examples for Python class #6 http://www.lib.uchicago.edu/keith/courses/python/class/6/ """ import UserDict from copy import copy class lazyconst: """ Infinite lazy list of some constant: e.g. lazyconst(0) is an infinite list of zeroes. """ def __init__(self, const): self.const = const def __len__(self): # prevents use with map, filter and reduce raise TypeError, "infinite length" def __getitem__(self, index): return self.const def __repr__(self): return "[%s...]" % self.const def __getslice__(self, i, j): # won't work with negative slice indices because python will # try to call self.__len__ return [self.const] * (j-i) class defaultdict(UserDict.UserDict): """ A dictionary that returns a default value for keys that aren't present """ def __init__(self, default): UserDict.UserDict.__init__(self) self.default = default def __getitem__(self, key): return self.data.get(key, self.default) def has_key(self, key): return 1 class defaultdict(UserDict.UserDict): """ More sophisticated version of defaultdict: if sticky == 1, then merely looking up a value actually stores the value; this is good for mutable defaults, as it allows, e.g.: d = defaultdict([], sticky=1) d["whatever"].append(1) """ def __init__(self, default, sticky = 0): UserDict.UserDict.__init__(self) self.default, self.sticky = default, sticky def __getitem__(self, key): if self.sticky: if self.data.has_key(key): return self.data[key] else: # question: why do we need to use copy? # question: why do we use result? self.data[key] = result = copy(self.default) return result else: return self.data.get(key, self.default) def has_key(self, key): return 1 # why is quotedict(d, quote) better than doing: for k in d.keys(): # d[k] = quote(d[k]) because it's lazy: if you aren't going to use # every item in d, then there's no point in quoting them all ahead of # time. Typical usage: generating HTML: # """ ...
... %(foo)s ... """ % quotedict(vars(), cgi.escape) # or as a dictionary of registers for counting; see test code below class quotedict(UserDict.UserDict): def __init__(self, dict, quote): self.data = dict self.quote = quote def __getitem__(self, key): return self.quote(self.data[key]) class register: """ Mutable registers """ def __init__(self): self.n = 0 def __repr__(self): return `self.n` def __coerce__(self, other): return (self.n, other) def __int__(self): return self.n def __cmp__(self, other): return cmp(self.n, int(other)) def __nonzero__(self): return self.n def inc(self, step=1): self.n = self.n + step return self.n def dec(self, step=1): self.n = self.n - step return self.n if __name__ == "__main__": from sys import argv from re import split from string import lower Usage = "%s filename" % argv[0] if len(argv) < 2: raise 'UsageError', Usage file = argv[1] d = defaultdict(register(), sticky=1) for word in map(lower, filter(None, split(r"[^a-zA-Z0-9']+", open(file).read()))): d[word].inc() counts = d.items() counts.sort() for (word, count) in counts: print "%7d\t%s" % (count, word) from os import environ from cgi import escape d = quotedict(environ, escape) for k in d.keys(): print d[k]