Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python, __slots__, inheritance, and class variables ==> attribute is read-only bug

Tags:

People also ask

What does using __ slots __ within a class in Python do?

Python | Use of __slots__ slots provide a special mechanism to reduce the size of objects.It is a concept of memory optimisation on objects. As every object in Python contains a dynamic dictionary that allows adding attributes.

How slots work Python?

Slots in Python is a special mechanism that is used to reduce memory of the objects. In Python, all the objects use a dynamic dictionary for adding an attribute. Slots is a static type method in this no dynamic dictionary are required for allocating attribute.

What is the __ dict __ attribute of an object in Python?

A special attribute of every module is __dict__. This is the dictionary containing the module's symbol table. A dictionary or other mapping object used to store an object's (writable) attributes.


I have a big tree with hundreds of thousands of nodes, and I'm using __slots__ to reduce the memory consumption. I just found a very strange bug and fixed it, but I don't understand the behavior that I saw.

Here's a simplified code sample:

class NodeBase(object):
    __slots__ = ["name"]
    def __init__(self, name):
        self.name = name

class NodeTypeA(NodeBase):
    name = "Brian"
    __slots__ = ["foo"]

I then execute the following:

>>> node = NodeTypeA("Monty")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
AttributeError: 'NodeTypeA' object attribute 'name' is read-only

There is no error if NodeTypeA.name is not defined (side note: that attribute was there by mistake, and had no reason for being there). There is also no error if NodeTypeA.__slots__ is never defined, and it therefore has a __dict__.

The thing I don't understand is: why does the existence of a class variable in a superclass interfere with setting an instance variable in a slot in the child class?

Can anybody explain why this combination results in the object attribute is read-only error? I know my example is contrived, and is unlikely to be intentional in a real program, but that doesn't make this behavior any less strange.

Thanks,
Jonathan