advanced programming techniques and so uses the descriptor to get the attribute' value here' the complete code for the xmlshadow descriptor classclass xmlshadowdef __init__(selfattribute_name)self attribute_name attribute_name def __get__(selfinstanceowner=none)return xml sax saxutils escapegetattr(instanceself attribute_name)when the name_as_xml and description_as_xml objects are created we pass the name of the product class' corresponding attribute to the xmlshadow initializer so that the descriptor knows which attribute to work on thenwhen the name_as_xml or description_as_xml attribute is looked uppython calls the descriptor' __get__(method the self argument is the instance of the descriptorthe instance argument is the product instance ( the product' self)and the owner argument is the owning class (product in this casewe use the getattr(function to retrieve the relevant attribute from the product (in this case the relevant property)and return an xml-escaped version of it if the use case was that only small proportion of the products were accessed for their xml stringsbut the strings were often long and the same ones were frequently accessedwe could use cache for exampleclass cachedxmlshadowdef __init__(selfattribute_name)self attribute_name attribute_name self cache {def __get__(selfinstanceowner=none)xml_text self cache get(id(instance)if xml_text is not nonereturn xml_text return self cache setdefault(id(instance)xml sax saxutils escapegetattr(instanceself attribute_name))we store the unique identity of the instance as the key rather than the instance itself because dictionary keys must be hashable (which ids are)but we don' want to impose that as requirement on classes that use the cachedxmlshadow descriptor the key is necessary because descriptors are created per class rather than per instance (the dict setdefault(method conveniently returns the value for the given keyor if no item with that key is presentcreates new item with the given key and value and returns the value