finallywe have the property declaration at the bottom this is the magic it creates new attribute on the color class called namewhich now replaces the previous name attribute it sets this attribute to be propertywhich calls the two methods we just created whenever the property is accessed or changed this new version of the color class can be used exactly the same way as the previous versionyet it now does validation when we set the name attributec color("# ff""bright red"print( namebright red name "redprint( namered name "traceback (most recent call last)file ""line in file "setting_name_property py"line in _set_name raise exception("invalid name"exceptioninvalid name soif we' previously written code to access the name attributeand then changed it to use our property objectthe previous code would still workunless it was sending an empty property valuewhich is the behavior we wanted to forbid in the first place successbear in mind that even with the name propertythe previous code is not percent safe people can still access the _name attribute directly and set it to an empty string if they want to but if they access variable we've explicitly marked with an underscore to suggest it is privatethey're the ones that have to deal with the consequencesnot us properties in detail think of the property function as returning an object that proxies any requests to set or access the attribute value through the methods we have specified the property keyword is like constructor for such an objectand that object is set as the public facing member for the given attribute