You use descriptors every day. Every time you write @property , every time you call a method, every time you use @staticmethod or @classmethod , you are using the descriptor protocol. Most Python developers have no idea it exists as a unified mechanism. Once you see it, you cannot unsee it. What a Descriptor Is A descriptor is any object that defines at least one of three methods: __get__ , __set__ , or __delete__ . That is it. When an attribute lookup finds one of these objects sitting in a class's __dict__ , Python hands control over to the descriptor instead of returning the object directly. The minimal descriptor looks like this: class MyDescriptor : def __get__ ( self , obj , objtype = None ): print ( f " __get__ called: obj= { obj } , objtype= { objtype } " ) return 42 class MyClass : attr = MyDescriptor () instance = MyClass () instance . attr # prints: __get__ called: obj=<MyClass ...>, objtype=<class 'MyClass'> MyClass .…