0

I'm trying to make a VarDump class, where I can do:

vd.attribute = value

and

print vd.attribute

So, this is the code:

class VarDump:

    def __init__(self):
        self.dump={}

    def __setattr__(self,item,var):
        self.dump[item]=var

    def __getattr__(self,item):
        if not item in self.dump: return ""
        return self.dump[item]

vd = VarDump()
vd.foo="bar"
print vd.foo

But I'm getting this error:

File "classAsVarDump.py", line 9, in __getattr__
    if not item in self.dump: return ""
RuntimeError: maximum recursion depth exceeded
Nacib Neme
  • 859
  • 1
  • 17
  • 28

3 Answers3

2

self.dump={} calls __setattr__ to set dump, which calls __getattr__ to get the dump to put dump into, which calls __getattr__ to get the dump, etc. You could resolve this with object.__setattr__, but the easier way is to just do this:

class Namespace(object):
    def __getattr__(self, attr):
        return ''

__getattr__ is only called when the attribute isn't found by normal means, so this doesn't need to handle looking up attributes that have actually been set.

user2357112
  • 260,549
  • 28
  • 431
  • 505
2

In Python 3.3, use the new types.SimpleNamespace() type instead:

>>> from types import SimpleNamespace
>>> vd = SimpleNamespace()
>>> vd.foo = 'bar'
>>> print(vd.foo)
bar

The documentation gives you a backwards-compatible version on a platter:

class SimpleNamespace:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
    def __repr__(self):
        keys = sorted(self.__dict__)
        items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
        return "{}({})".format(type(self).__name__, ", ".join(items))

The only difference between your version and this one is that this one doesn't use __setattr__ and __getattr__ (not needed at all), this version takes initial values in the initializer, and it includes a nice representation:

>>> vd
namespace(foo='bar')
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

No need to override __setattr__ or __getattr__

>>> class VarDump(object):
...     pass
... 
>>> c = VarDump()
>>> c.bar = 2
>>> print c.bar
2
Kimvais
  • 38,306
  • 16
  • 108
  • 142