On Fri, Mar 11, 2016 at 10:59 PM, Veek. M <vek.m1...@gmail.com> wrote: > A property uses the @property decorator and has @foo.setter > @foo.deleter. > > A descriptor follows the descriptor protocol and implements the __get__ > __set__ __delete__ methods. > > But they both do essentially the same thing, allow us to do: > foo = 10 > del foo > x = foo > > So why do we have two ways of doing this?
Properties *are* descriptors. Properties just provide a more natural syntax for a very common case. > Also, > ##################### > 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.default) > > def __set__(self,instance,value): > if not isinstance(value,self.type): > raise TypeError("Must be a %s" % self.type) > setattr(instance,self.name,value) > > def __delete__(self,instance): > raise AttributeError("Can't delete attribute") > > class Foo(object): > name = TypedProperty("name",str) > num = TypedProperty("num",int,42) > > In this example, the class TypedProperty defines a 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 example: > > f = Foo() > a = f.name # Implicitly calls Foo.name.__get__(f,Foo) > f.name = "Guido" # Calls Foo.name.__set__(f,"Guido") > del f.name # Calls Foo.name.__delete__(f) > ################################## > > I didn't follow this. Foo is a composition of TypedProperty. > You've got a 'Foo' type with two attributes 'name' and 'num'. > When you do f.name you are actually doing: > f.name.__get__(self, instance, cls) More accurately, you're doing f.__class__.__dict__['name'].__get__(self, instance, cls). But yes, this is how the descriptor protocol works. > What the heck?? > > I didn't follow this example at all.. What is he doing in there? > Also, what's this bit: > self.default = default if default else type() If the default parameter has a truthy value, it gets set to self.default. Otherwise, the type parameter is called with no arguments, and the resulting instance is used as self.default instead. -- https://mail.python.org/mailman/listinfo/python-list