6. Setattr, Getattr

6.1. Built-in Functions

  • setattr(obj, 'attribute_name', 'new value') -> None

  • getattr(obj, 'attribute_name', 'default value') -> Any

  • hasattr(obj, 'attribute_name') -> bool

  • delattr(obj, 'attribute_name') -> None

  • getattr(x, 'name') is equivalent to x.name

6.2. Protocol

  • __setattr__(object, attribute_name, value)

  • __getattribute__(object, attribute_name, default)

  • __getattr__(object, attribute_name, default)

  • __delattr__(object, attribute_name)

6.3. __setattr__()

  • setattr(x, 'name', 'value')

Listing 370. Example __setattr__()
class Temperature:
    def __init__(self, initial_temperature):
        self.value = initial_temperature

    def __setattr__(self, attribute_name, new_value):
        if attribute_name == 'value' and new_value < 0.0:
            raise ValueError('Kelvin temperature cannot be negative')
        else:
            object.__setattr__(self, attribute_name, new_value)


t = Temperature(100)

t.value = 20
print(t.value)
# 20

t.value = -10
# ValueError: Kelvin temperature cannot be negative

6.4. __delattr__()

  • del x.name

  • delattr(x, 'name')

Listing 371. Example __delattr__()
class Temperature:
    def __init__(self, initial_temperature):
        self.value = initial_temperature

    def __delattr__(self, attribute_name):
        if attribute_name == 'value':
            self.value = 0.0
        else:
            object.__delattr__(self, attribute_name)


t = Temperature(100)

del t.value
print(t.value)
# 0.0

6.5. __getattribute__()

  • Called for every time, when you want to access any attribute

  • Before even checking if this attribute exists

  • __getattribute__() is called before __getattr__()

  • if __getattribute__() raises AttributeError exception, then the exception will be ignored and __getattr__() method will be invoked

Listing 372. Example __getattribute__()
class Temperature:
    def __init__(self, initial_temperature):
        self.value = initial_temperature

    def __getattribute__(self, attribute_name):
        if attribute_name == 'value':
            raise PermissionError('Field is private')
        else:
            return object.__getattribute__(self, attribute_name)


temp = Temperature(273)

temp.value = 20
print(temp.value)
# PermissionError: Field is private

6.6. __getattr__()

  • Called whenever you request an attribute that hasn't already been defined

  • getattr(x, 'name') is equivalent to x.name

  • When __getattribute__() raised an AttributeError

  • Implementing a fallback for missing attributes

6.7. hasattr()

  • Check if object has attribute

  • There is no __hasattr__() method

  • Triggers __getattribute__()

6.8. Assignments

6.8.1. Immutable classes

English
  1. Create class Point with x, y, z attributes

  2. Prevent adding new attributes

  3. Prevent deleting attributes

  4. Prevent changing attributes

  5. Allow to set attributes only at the initialization

Polish
  1. Stwórz klasę Point z atrybutami x, y, z

  2. Zablokuj możliwość dodawania nowych atrybutów

  3. Zablokuj możliwość usuwania atrybutów

  4. Zablokuj edycję atrybutów

  5. Pozwól na ustawianie atrybutów tylko przy inicjalizacji klasy