Pavel Volkov <sai...@lists.xtsubasa.org> wrote: > There are some basics about Python objects I don't understand. > Consider this snippet: > >>>> class X: pass > ... >>>> x = X() >>>> dir(x) > ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', > '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', > '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', > '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', > '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>>> x.foo = 11 > > And now I want to make a simple object in a shorter way, without > declaring X class: > >>>> y = object() >>>> dir(y) > ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', > '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', > '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', > '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', > '__subclasshook__'] >>>> y.foo = 12 > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > AttributeError: 'object' object has no attribute 'foo' > > The attribute list is different now and there's no __dict__ and the > object does not accept new attributes. > Please explain what's going on. > > Not all classes have a __dict__ attribute. Mostly builtin classes (e.g. tuple, list, int, ...), but also if you have an class using __slots__ which subclasses a class with no __dict__ it won't have a __dict__.
Subclasses don't remove attributes, they only add them (although in Python you can bend that rule it still applies here). Therefore for any classes to not have a __dict__ attribute the ultimate base class 'object' has to not have a __dict__. The consequence, as you found out, is that you cannot add attributes to an instance of 'object()', you have to create at least an empty subclass which doesn't include a `__slots__` attribute to get a class that can accept arbitrary attributes. -- Duncan Booth -- https://mail.python.org/mailman/listinfo/python-list