views:

82

answers:

2

Hi all, in Ruby, there's this awesome library called a Mash which is a Hash but through clever use of missing_method can convert:

object['property']

to

object.property

This is really useful for mocks. Anyone know of a similar kind of thing in Python?

+2  A: 

Is __getitem__ what you're looking for?

class C:
   def __init__(self):
      self.my_property = "Hello"

   def __getitem__(self, name):
      return getattr(self, name)

c = C()
print c['my_property']  # Prints "Hello"

or are you looking for the reverse of that, via__getattr__?

class D(dict):
   def __getattr__(self, name):
      return self[name]

d = D()
d['x'] = "Hello"
print d.x  # Prints "Hello"

(Edit: As Paul McGuire kindly points out in the comments, this code only demonstrates the bare bones of a full solution.)

RichieHindle
For more complete attribute emulation, also implement `__dir__` to return all dict's attributes, plus all user-specified names.
Paul McGuire
Will conflict with dict's own attributes, like items, values, etc. since `__getattr__` will only get called if no attribute is found. So d['items'] can be set, but can never be retrieved by this `__getattr__`. To work around this, write D to contain and delegate to a dict, rather than inherit from dict.
Paul McGuire
Lastly, the OP is trying to write mocks, so `__setattr__` is probably going to come into the picture at some point, so that `x.xyzzy` can be written as well as read.
Paul McGuire
+5  A: 

Is it absolutely necessary that you base this on a dict? Python objects can dynamically acquire attributes with very little extra plumbing:

>>> class C(object): pass
...
>>> z = C()
>>> z.blah = "xyzzy"
>>> dir(z)
['__class__', '__delattr__', '__dict__', ... '__weakref__', 'blah']
Paul McGuire
Wow that's great thanks! I'd love to give extra points for such a fast answer too :)
Julian