-2

There's some strange behavior with slots i currently do not understand. Using self.__slots__[0] = _value to set a value for the attribute define in the __slots__ list, the only way to read its value is by accessing the same element in the list self.__slots__[0].

If i were to attempt to access the value through a.slot_0, it results in an AttributeError. However setting the value through

self.slot_0 = _value

allows the value to be accessed by a.slot_0. What is the reasoning for this behavior?

It seems the list is being updated with the intended value for the string attribute, but even though the list attribute is overwritten e.g slot_0, the attribute remains on the instance's namespace shown by dir(a)

If this is intended behavior, to allow the __slots__ list to store the values for the initial attributes. While overwriting those attributes. Which method is preferable, mutating the list with values or initializing the attributes with values.

__slots__[o] = ... vs instance.Attribute = ...?

class Example3():
    __slots__ = ["slot_0"]
    
    def set_0(self, _value):
        #self.slot_0 = _value
        self.__slots__[0] = _value
        
    def get_0(self):
        return self.__slots__[0]
    
a = Example3()
b = Example3()

a.set_0("zero")
#print(a.get_0())
print(a.slot_0)
print(dir(a))
print(a.__slots__)
Traceback (most recent call last):
  File "c:\Users\Dell\Desktop\PythonPlayground\slots.py", line 51, in <module>
    print(a.slot_0)
AttributeError: 'Example3' object has no attribute 'slot_0'. Did you mean: 'set_0'?
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', 
 '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
 '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', 
 '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
 '__slots__', '__str__', '__subclasshook__', 'get_0', 'set_0', 'slot_0']


['zero']
Karl Knechtel
  • 56,349
  • 8
  • 83
  • 124
  • 2
    "Using `self.__slots__[0] = _value` to set a value for the attribute define in the slots list" **does not make sense**. Even though you use `self` for the lookup, `__slots__` is an attribute of **the class**, not the instance. "If this is intended behavior, to allow the slots list to store the values for the initial attributes." No, `__slots__` has a **completely unrelated** purpose. You should understand that purpose by going back to where-ever it was that you found out that there is such a thing as `__slots__`, and *reading the surrounding text more carefully*. – Karl Knechtel Jun 04 '22 at 11:33
  • Welcome to Stack Overflow. Please read [ask] and the [formatting help](https://stackoverflow.com/help/formatting). Please use inline code spans for code that is embedded within the paragraph, and format error messages and code output like multi-line code. – Karl Knechtel Jun 04 '22 at 11:34
  • Heres where i got the information: https://wiki.python.org/moin/UsingSlots – ThreadBucks Jun 04 '22 at 11:37
  • I see. I wish to highlight the following quotation: "`__slots__` is a class variable that is usually assigned a sequence of strings that are variable names used by instances." Notice: class variable, **not** instance variable. Notice: variable names, **not** initial values. (It really should say "attribute" rather than "variable" in each case here.) – Karl Knechtel Jun 04 '22 at 11:40
  • Ah okay, you're completely right. Since `__slots__` is a class attributes, by setting the value using the list `__slots__`. The value would propagate to each instance of the class. So it cannot be a reliable way to set instance variables. My main confusion was the string attributes in the `__slots__` remaining in the dir() of the instance even after overwriting their values in the `__slots__`. It made me think this could be another way to set instance variables. But i think the initial text used `__slots__[0]` to demonstrate the shared nature of the `__slots__` class variable list. – ThreadBucks Jun 04 '22 at 11:46
  • Not quite a proper duplicate, I think, but see also: https://stackoverflow.com/questions/11007627/python-variable-declaration for important and relevant information. – Karl Knechtel Jun 04 '22 at 11:50
  • "My main confusion was the string attributes in the __slots__ remaining in the dir() of the instance even after overwriting their values in the __slots__" Yes; that is because the contents of `__slots__` are used *when the class is created*, to define additional setup logic for the class. Each newly created instance will have *those* named attributes, even if `__slots__` changed in the mean time. (Note that `AttributeError` will still be raised by an attempt to read those attributes before setting them - they do not get a default value - but with a different message.) – Karl Knechtel Jun 04 '22 at 11:54

0 Answers0