1

Somebody recently pointed me to the usage of __slots__ What I could find on the internet is that it could improve memory usage

class Passenger2():
    __slots__ = ['first_name', 'last_name']
    def __init__(self, iterable=(), **kwargs):
        for key, value in kwargs:
            setattr(self, key, value)

class Passenger():
    def __init__(self, iterable=(), **kwargs):
        self.__dict__.update(iterable, **kwargs)

# NO SLOTS MAGIC works as intended
p = Passenger({'first_name' : 'abc', 'last_name' : 'def'})
print(p.first_name)
print(p.last_name)

# SLOTS MAGIC
p2 = Passenger2({'first_name' : 'abc', 'last_name' : 'def'})
print(p2.first_name)
print(p2.last_name)

While the First class works as intended, the second class will give me an attribute-error. What is the correct usage of the __slots__

Traceback (most recent call last):
  File "C:/Users/Educontract/AppData/Local/Programs/Python/Python36-32/tester.py", line 10, in <module>
    print(p.first_name)
AttributeError: first_name
Ludisposed
  • 1,709
  • 4
  • 18
  • 38
  • 3
    1. When you pass a dictionary object, the `kwargs` is empty. 2. If you need key-value pairs of a dictionary, iterate over `dict.items`. – vaultah Jul 26 '17 at 09:58
  • 1
    Please refer this, https://stackoverflow.com/questions/472000/usage-of-slots – Mohd Sheeraz Jul 26 '17 at 10:01

1 Answers1

3

Unpack the keyword arguments you supply:

p2 = Passenger2(**{'first_name' : 'abc', 'last_name' : 'def'})

and iterate through kwargs.items() to grab the key-value pair.

In the call you're performing:

p2 = Passenger2({'first_name' : 'abc', 'last_name' : 'def'})

the dictionary you supply gets assigned to iterable and not kwargs because you pass it as a positional. **kwargs is empty in this case and no assigning is performed.

Remember, **kwargs grabs the excess keyword arguments not just any dictionary that is passed.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253