1

My question is pretty simple, I have:

class upperstr(str):
    def __new__(cls, arg):
        return str.__new__(cls, str(arg).upper())

Why, if my __new__() method is directly using an instance of an inmutable type (str), instances of my new type (upperstr) are mutable?

>>> s = str("text")
>>> "__dict__" in dir(s)
False
>>> s = upperstr("text")
>>> "__dict__" in dir(s)
True

In what stage does the interpreter sets the __dict__ attribute to upperstr intances if I'm only overriding the __new__() method?

Thanks!

joaquin
  • 82,968
  • 29
  • 138
  • 152
Anler
  • 1,793
  • 13
  • 21
  • "Has `__dict__`" does **not** imply "is mutable". –  Nov 26 '11 at 12:40
  • Related: [How to make an immutable object in Python?](http://stackoverflow.com/questions/4828080/how-to-make-an-immutable-object-in-python) – Sven Marnach Nov 26 '11 at 12:49

1 Answers1

7

All user-defined classes in Python have a __dict__() attribute by default, even if you don't overwrite anything at all:

>>> x = object()
>>> x.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute '__dict__'
>>> class MyObject(object):
...     pass 
... 
>>> x = MyObject()
>>> x.__dict__
{}

If you don't want a new-style class to have a __dict__, use __slots__ (documentation, related SO thread):

>>> class MyObject(object):
...     __slots__ = []
... 
>>> x = MyObject()
>>> x.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyObject' object has no attribute '__dict__'
Community
  • 1
  • 1
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841