0

From the python docs 3.3.2.4.1, it says "__slots__ declared in parents are available in child classes. However, child subclasses will get a __dict__ and __weakref__ unless they also define __slots__ (which should only contain names of any additional slots)."

However, while I was testing this as below:

class A(object):
    __slots__ = ('a')

class B(A):
    __slots__ = ('b')

b = B()
B.z = 'z'
B.a = 'a'
print(B.z) #z
print(B.a) #a
print(B.__dict__) #{'__module__': '__main__', '__slots__': ('b',), 'b': <member 'b' of 'B' objects>, '__doc__': None, 'z': 'z', 'a': 'a'}

Neither B.z nor B.__dict__ throws exception, the code manages to output.

I am confused why the __slots__ = ('b') in Class B doesn't validate. Theoretically, it should throw an exception at B.z because the keys in slots don't contain it.

Could you please help to explain this strange point? And if possible, could you please help to provide the right usage method of slots in child classes?

By the way, my python version is 3.9.7

Thank you so much.

Grylls Leong
  • 11
  • 1
  • 3

1 Answers1

0

The __slots__ should be a tuple there, but you don't actually have a tuple, you have a string. Try doing __slots__ = ("a",).

Also, the slots apply to instances, not classes. You are assigning the attribute to the class object. Try the following. The instances work as expected.

a = A()
a.a = "a"
# a.b = "b"  # fails

b = B()
b.b = "b"
b.a = 'a'
# b.z = 'z'  # fails
Keith
  • 42,110
  • 11
  • 57
  • 76
  • Oh thank you so much for your help! And now I've known why I see some example uses __slots__ = ('a',)instead of ('a'). It's true it apply to instances so I should use b instead of the class B! Thank you again for your kindly help!! – Grylls Leong Feb 12 '22 at 15:44