Ian Kelly wrote:
> 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. thanks okay i'll read that and get back > >> 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. But type() just gives me: TypeError: type() takes 1 or 3 arguments on py2,3 -- https://mail.python.org/mailman/listinfo/python-list