osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Extending property using a Subclass - single method - why Super(Baz, Baz).name.__set__ ?


Veek M wrote:

> class Foo(object):
>     @property
>     def name(self):
>         if hasattr(self, '_name'):
>             print('Foo name', self._name)
>             return self._name
>         else:
>             return 'default'
> 
>     @name.setter
>     def name(self, value):
>         print('Foo', self)
>         self._name = value
>         print(self._name)
>         
>     @name.deleter
>     def name(self):
>         print('del')
>         self._name = None
>     
>     print('Foo', name)
> 
> class Baz(Foo):
>     @property
>     def name(self):
>         print('Baz wrapper around getter')
>         return super().name
>         
>     @Foo.name.setter

This looks like a bug as the read-only property defined above is overwritten 
by a copy of the name poperty of the base class (with an updated setter).

>     def name(self, value):
>         print('Baz wrapper around setter')
>         print(self)
>         print(super(Baz,Baz).name, value)
>         return super(Baz, Baz).name.__set__(self, value)

When you want to invoke a method of the base class property you have to look 
up that property in the base class. This is what super(Baz, Baz).name does.

super().name

for read access is an exception. The __get__() method is invoked implicitly 
which is probably also the reason why you cannot write 
super().name.somepropertymethod(...) for anything else.


>     
> b = Baz()
> print('print', b.name)
> b.name = 'v'
> print(b.name)
> 
> Why do we user super(Baz, Baz) - are we setting a class variable called
> Baz.name which would trigger Baz._name = value?
> 
> We are essentially doing:
> Foo.name.__set__(Baz, value) ?
> 
> How come 'self' is not used.. like in the traditional property way where
> we pass an instance reference instead of a class?