Descriptors vs Property
Ian Kelly
ian.g.kelly at gmail.com
Sat Mar 12 01:12:24 EST 2016
On Fri, Mar 11, 2016 at 10:59 PM, Veek. M <vek.m1234 at 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.
More information about the Python-list
mailing list