list( __dict__ keys()[' ' ( get get stored on xhiding ay still inherits descriptor this is the way all instance attribute assignments work in pythonand it allows classes to selectively override class-level defaults in their instances to make descriptor-based attribute read-onlycatch the assignment in the descriptor class and raise an exception to prevent attribute assignment--when assigning an attribute that is descriptorpython effectively bypasses the normal instance-level assignment behavior and routes the operation to the descriptor objectclass ddef __get__(*args)print('get'def __set__(*args)raise attributeerror('cannot set'class ca ( ( get attributeerrorcannot set routed to __get__ routed to __set__ also be careful not to confuse the descriptor __delete__ method with the general __del__ method the former is called on attempts to delete the managed attribute name on an instance of the owner classthe latter is the general instance destructor methodrun when an instance of any kind of class is about to be garbage-collected __delete__ is more closely related to the __delattr__ generic attribute deletion method we'll meet later in this see for more on operator overloading methods first example to see how this all comes together in more realistic codelet' get started with the same first example we wrote for properties the following defines descriptor that intercepts access to an attribute named name in its clients its methods use their instance argument to access state information in the subject instancewhere the name string is actually stored like propertiesdescriptors work properly only for new-style classesso be sure to derive both classes in the following from object if you're using --it' not enough to derive just the descriptoror just its clientdescriptors