Descriptor Protocols

Fri 09 January 2026
class Descriptor:
    def __get__(self, instance, owner):
        print("Getting value")
        return instance._value

    def __set__(self, instance, value):
        print("Setting value")
        instance._value = value

class MyClass:
    attribute = Descriptor()

obj = MyClass()
obj.attribute = 42  # Setting value
print(obj.attribute)  # Getting value, Output: 42
Setting value
Getting value
42
class ReadOnlyDescriptor:
    def __get__(self, instance, owner):
        return "This is a read-only attribute"

    def __set__(self, instance, value):
        raise AttributeError("Cannot modify read-only attribute")

class MyClass:
    read_only = ReadOnlyDescriptor()

obj = MyClass()
print(obj.read_only)  # Output: This is a read-only attribute
# obj.read_only = "New value"  # Raises AttributeError
This is a read-only attribute
class PositiveNumber:
    def __get__(self, instance, owner):
        return instance._number

    def __set__(self, instance, value):
        if value < 0:
            raise ValueError("Number must be positive")
        instance._number = value

class MyClass:
    number = PositiveNumber()

obj = MyClass()
obj.number = 10
print(obj.number)  # Output: 10
# obj.number = -5  # Raises ValueError
10
class NonDataDescriptor:
    def __get__(self, instance, owner):
        return "Non-data descriptor called"

class MyClass:
    attribute = NonDataDescriptor()

obj = MyClass()
print(obj.attribute)  # Output: Non-data descriptor called
Non-data descriptor called
class Descriptor:
    def __get__(self, instance, owner):
        return "Class-level descriptor"

class MyClass:
    attribute = Descriptor()

print(MyClass.attribute)  # Output: Class-level descriptor
Class-level descriptor
class Descriptor:
    def __get__(self, instance, owner):
        return instance.__dict__.get("_value", None)

    def __set__(self, instance, value):
        print(f"Setting value to {value}")
        instance.__dict__["_value"] = value

class MyClass:
    attribute = Descriptor()

obj = MyClass()
obj.attribute = "Hello"
print(obj.attribute)  # Output: Hello
Setting value to Hello
Hello
class TrackingDescriptor:
    def __init__(self):
        self.access_count = 0

    def __get__(self, instance, owner):
        self.access_count += 1
        return f"Accessed {self.access_count} times"

class MyClass:
    tracked = TrackingDescriptor()

obj = MyClass()
print(obj.tracked)  # Output: Accessed 1 times
print(obj.tracked)  # Output: Accessed 2 times
Accessed 1 times
Accessed 2 times
class ControlledAttribute:
    def __get__(self, instance, owner):
        return instance.__dict__.get(self.name)

    def __set__(self, instance, value):
        print(f"Setting {self.name} to {value}")
        instance.__dict__[self.name] = value

    def __set_name__(self, owner, name):
        self.name = name

class MyClass:
    attr1 = ControlledAttribute()
    attr2 = ControlledAttribute()

obj = MyClass()
obj.attr1 = "Value 1"
obj.attr2 = "Value 2"
print(obj.attr1, obj.attr2)  # Output: Value 1 Value 2
Setting attr1 to Value 1
Setting attr2 to Value 2
Value 1 Value 2
class LoggedDescriptor:
    def __get__(self, instance, owner):
        print(f"Accessing {self.name}")
        return instance.__dict__.get(self.name)

    def __set__(self, instance, value):
        print(f"Setting {self.name} to {value}")
        instance.__dict__[self.name] = value

    def __set_name__(self, owner, name):
        self.name = name

class MyClass:
    logged_attr = LoggedDescriptor()

obj = MyClass()
obj.logged_attr = "Testing"
print(obj.logged_attr)
Setting logged_attr to Testing
Accessing logged_attr
Testing
class Temperature:
    def __get__(self, instance, owner):
        return (instance._celsius * 9/5) + 32  # Convert Celsius to Fahrenheit

    def __set__(self, instance, value):
        instance._celsius = value  # Store value in Celsius

class Weather:
    temperature = Temperature()

weather = Weather()
weather.temperature = 25  # Setting in Celsius
print(weather.temperature)  # Output: 77.0 (Fahrenheit)
77.0


Score: 10

Category: Descriptor Protocols

Page 1 of 1