class typedproperty(object)def _init_ (self,name,type,default=none)self name "_name self type type self default default if default else type(def _get_ (self,instance,cls)return getattr(instance,self name,self defaultdef _set_ (self,instance,value)if not isinstance(value,self type)raise typeerror("must be %sself typesetattr(instance,self name,valuedef _delete_ (self,instance)raise attributeerror("can' delete attribute"class foo(object)name typedproperty("name",strnum typedproperty("num",int, in this examplethe class typedproperty defines descriptor where type checking is performed when the attribute is assigned and an error is produced if an attempt is made to delete the attribute for examplef foo( name name "guidodel name implicitly calls foo name _get_ ( ,foocalls foo name _set_ ( ,"guido"calls foo name _delete_ (fdescriptors can only be instantiated at the class level it is not legal to create descriptors on per-instance basis by creating descriptor objects inside _init_ (and other methods alsothe attribute name used by the class to hold descriptor takes precedence over attributes stored on instances in the previous examplethis is why the descriptor object takes name parameter and why the name is changed slightly by inserting leading underscore in order for the descriptor to store value on the instanceit has to pick name that is different than that being used by the descriptor itself data encapsulation and private attributes by defaultall attributes and methods of class are "public "this means that they are all accessible without any restrictions it also implies that everything defined in base class is inherited and accessible within derived class this behavior is often undesirable in object-oriented applications because it exposes the internal implementation of an object and can lead to namespace conflicts between objects defined in derived class and those defined in base class to fix this problemall names in class that start with double underscoresuch as _fooare automatically mangled to form new name of the form _classname_ _foo this effectively provides way for class to have private attributes and methods because private names used in derived class won' collide with the same private names used in base class here' an exampleclass (object)def _init_ (self)self _x def _spam(self)pass def bar(self)self _spam(mangled to self _a_ _x mangled to _a_ _spam(only calls _spam( lib fl ff