non-data descriptor non-data descriptor stores the assigned values in the dictionary as shown belownon_data_descriptor py class nondatadescriptor(object)""descriptor example ""def __init__(self)self value def __get__(selfinstancecls)print("non-data descriptor __get__"return self value class (object)attr nondatadescriptor( (print( attrnon-data descriptor __get__ attr attr print( __dict__{'attr' importantin non-data descriptorthe assigned values are stored in instance dictionary (and only last assigned value is stored in dictionary)whereas data descriptor assigned values are stored in descriptor dictionary because the set method of descriptor is invoked __getattribute__ breaks the descriptor usage in below code__getattribute__ method is overridden in class overriden theninstance of class overriden is created and finally the descriptor is called at line in this case__getattribute__ method is invoked first and does not give access to descriptor non_data_descriptor py class nondatadescriptor(object)""descriptor example ""def __init__(self)self value def __get__(selfinstancecls)print("non-data descriptor __get__"return self value class overriden(object)attr nondatadescriptor(def __getattribute__(selfname)print("sorryno way to reach to descriptor!" overriden( attr sorryno way to reach to descriptor descriptors