magical expanding hash

James Stroud jstroud at ucla.edu
Tue Jan 17 19:47:15 EST 2006


braver wrote:
> Well, I know some python, but since there are powerful and magical
> features in it, I just wonder whether there're some which address this
> issue better than others.
> 

In python, += is short, of course, for

a = a + 1

But if we haven't already assigned a, how does the interpreter know that 
we want an int, float, complex, long, or some other data-type that 
defines "+"?

Better, clearer or more pythonic would be:

a = 0.0     # we want a float, compiler didn't have to read mind
b = 0       # now we want an int, saving compiler lots of guesswork
a += 1      # incrementing a float by one

The "<<" operator corresponds to the __lshift__ magic method. You can
make a custom data-type here:

class lshiftinglist(list):
   def __lshift__(self, value):
     list.append(self, value)

class meh(dict):
   def __getitem__(self, item):
     return dict.setdefault(self, item, meh())

m = meh()
m['bob']['carol'] = 1
m['bob']['carol'] += 1
m['bob']['ted'] = lshiftinglist()
m['bob']['ted'] << 42
m['bob']['ted'] << 43

print m   # {'bob': {'carol': 2, 'ted': [42, 43]}}


Other than magically reading mind of programmer, this works pretty much
according to specification.

If you really want a lot of mindreading abilities, you have to write
your own mindreading code. Here is a tiny example:

class meh(dict):
   def __getitem__(self, item):
     return dict.setdefault(self, item, meh())
   def __getattr__(self, attr):
     return self.ga(attr)
   def __lshift__(self, value):
     print "You are thinking of '%s'." % value
   def __iadd__(self, other):
     # don't try this on a populated meh!!!!!
     return other

m = meh()

# mindreading way
m['carol'] += 4
m['carol'] += 5
m['bob'] << 44   # "You are thinking of '44'."

# better, not mindreading way
m['alice'] = [10]
m['alice'].append(11)
m['ted'] = 18
m['ted'] += 1

print m   # "{'carol': 9, 'ted': 19, 'bob': {}, 'alice': [10, 11]}"


It would take a lot of coding to make that << work right. Better is the 
pythonic

m[key] = [value]

Its really only one more keystroke than

m[key] << value


James



More information about the Python-list mailing list