def __init__(selfdata)self data data def __get__(selfinstanceowner)return '% % (self datainstance datadef __set__(selfinstancevalue)instance data value class clientdef __init__(selfdata)self data data managed descboth('spam' client('eggs' managed 'spameggsi managed 'spami managed 'spamspamshow both data sources change instance data we'll revisit the implications of this choice in larger case study later in this before we move onrecall from ' coverage of slots that we can access "virtualattributes like properties and descriptors with tools like dir and getattreven though they don' exist in the instance' namespace dictionary whether you should access these this way probably varies per program--properties and descriptors may run arbitrary computationand may be less obviously instance "datathan slotsi __dict__ {'data''spam'[ for in dir(iif not startswith('__')['data''managed'getattr( 'data''spamgetattr( 'managed''spamspamfor attr in ( for in dir(iif not startswith('__'))print('% =% (attrgetattr(iattr))data =spam managed =spamspam the more generic __getattr__ and __getattribute__ tools we'll meet later are not designed to support this functionality--because they have no class-level attributestheir "virtualattribute names do not appear in dir results in exchangethey are also not limited to specific attribute names coded as properties or descriptorstools that share even more than this behavioras the next section explains descriptors