Equivalent to Ruby Mash in Python?

in Ruby, there this amazing library is called Mash , which is a hash, but through smart use, missing_method can convert:

object['property'] 

to

 object.property 

This is really useful for mocks. Does anyone know similar things in Python?

+4
source share
4 answers

Do you absolutely need you to base this on the announcer? 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'] 
+6
source

Is __getitem__ what you are 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 opposite via __getattr__ ?

 class D(dict): def __getattr__(self, name): return self[name] d = D() d['x'] = "Hello" print dx # Prints "Hello" 

( Edit . As Paul McGuire notes in the comments, this code only shows the bare bones of a complete solution.)

+3
source

Do you absolutely need you to base this on a dict?

Yes, if you want to treat it as a list of items without abusing __dict__ .

The following is my old answer to the Mash question. It provides a default value, by default there can be a method or an object if it will clone the object deeply (and not just a hot link) if it is used more than once.

And it provides its simple key values ​​like .key :

 def Map(*args, **kwargs): value = kwargs.get('_default', None) if kwargs.has_key('_default'): del kwargs['_default'] # CONSIDER You may want to look at the collections.defaultdict class. # It takes in a factory function for default values. # # You can also implement your class by overriding the __missing__ method # of the dict class, rather than overriding the __getitem__. # # Both were added in Python 2.5 according to the documentation. class _DefMap(dict): 'But CONSIDER http://pypi.python.org/pypi/bunch/1.0.0 ' def __init__(self, *a, **kw): dict.__init__(self, *a, **kw) self.__dict__ = self def __getitem__(self, key): if not self.has_key(key): if hasattr(value, '__call__'): self[key] = value(key) else: self[key] = copy.deepcopy(value) return dict.__getitem__(self, key) return _DefMap(*args, **kwargs) 
+1
source

Take a look here https://pypi.python.org/pypi/mash . You can also convert a dict to a mash object.

0
source

All Articles