def __setattr__(selfattrvalue)if attr =' 'attr 'valueself __dict__[attrvalue on all attr assignments attrsquare( attrsquare( instances of class with overloading each has different state information print( xa print( xprint( * * * ( running this code results in the same output that we got earlier when using properties and descriptorsbut this script' mechanics are based on generic attribute interception methodsc:\codepy - getattr-computed py using __getattribute__ as beforewe can achieve the same effect with __getattribute__ instead of __get attr__the following replaces the fetch method with __getattribute__ and changes the __setattr__ assignment method to avoid looping by using direct superclass method calls instead of __dict__ keysclass attrsquaredef __init__(selfstart)self value start add (objectfor triggers __setattr__def __getattribute__(selfattr)on all attr fetches if attr =' 'return self value * triggers __getattribute__ againelsereturn object __getattribute__(selfattrdef __setattr__(selfattrvalue)on all attr assignments if attr =' 'attr 'valueobject __setattr__(selfattrvaluewhen this versiongetattribute-computed pyis runthe results are the same again noticethoughthe implicit routing going on inside this class' methodsself value=start inside the constructor triggers __setattr__ self value inside __getattribute__ triggers __getattribute__ again in fact__getattribute__ is run twice each time we fetch attribute this doesn' happen in the __getattr__ versionbecause the value attribute is not undefined if you care managed attributes