programacion poo otra orientada objetos metodo llamar lista instancia importar herencia clases clase python inheritance properties overloading descriptor

otra - poo python 3



¿Cómo llamar a una propiedad de la clase base si esta propiedad se sobrescribe en la clase derivada? (5)

Existe una alternativa que usa super que no requiere referencia explícita del nombre de la clase base.

Clase base A:

class A(object): def __init__(self): self._prop = None @property def prop(self): return self._prop @prop.setter def prop(self, value): self._prop = value class B(A): # we want to extend prop here pass

En B, accediendo al captador de propiedad de la clase padre A:

Como otros ya han respondido, es:

super(B, self).prop

O en Python 3:

super().prop

Esto devuelve el valor devuelto por el captador de la propiedad, no el captador en sí, pero es suficiente para extender el captador.

En B, acceder al conjunto de propiedades de la clase principal A:

La mejor recomendación que he visto hasta ahora es la siguiente:

A.prop.fset(self, value)

Creo que este es mejor:

super(B, self.__class__).prop.fset(self, value)

En este ejemplo, ambas opciones son equivalentes, pero el uso de super tiene la ventaja de ser independiente de las clases base de B Si B fuera a heredar de una clase C también extiende la propiedad, no tendrías que actualizar el código de B

Código completo de B que extiende la propiedad de A:

class B(A): @property def prop(self): value = super(B, self).prop # do something with / modify value here return value @prop.setter def prop(self, value): # do something with / modify value here super(B, self.__class__).prop.fset(self, value)

Una advertencia:

A menos que su propiedad no tenga un setter, debe definir tanto el setter como el getter en B incluso si solo cambia el comportamiento de uno de ellos.

Estoy cambiando algunas clases de la mía desde un uso extensivo de getters y setters a un uso más pythonic de propiedades.

Pero ahora estoy atascado porque algunos de mis getters o setters anteriores llamaban al método correspondiente de la clase base, y luego realizaban otra cosa. Pero, ¿cómo se puede lograr esto con las propiedades? ¿Cómo llamar a la propiedad getter o setter en la clase principal?

Por supuesto, solo llamar al atributo en sí da una recursión infinita.

class Foo(object): @property def bar(self): return 5 @bar.setter def bar(self, a): print a class FooBar(Foo): @property def bar(self): # return the same value # as in the base class return self.bar # --> recursion! @bar.setter def bar(self, c): # perform the same action # as in the base class self.bar = c # --> recursion! # then do something else print ''something else'' fb = FooBar() fb.bar = 7


Podría pensar que podría llamar a la función de clase base a la que llama propiedad:

class FooBar(Foo): @property def bar(self): # return the same value # as in the base class return Foo.bar(self)

Aunque creo que es lo más obvio que intento , no funciona porque la barra es una propiedad, no es invocable.

Pero una propiedad es solo un objeto, con un método getter para encontrar el atributo correspondiente:

class FooBar(Foo): @property def bar(self): # return the same value # as in the base class return Foo.bar.fget(self)


tratar

@property def bar: return super(FooBar, self).bar

Aunque no estoy seguro de si Python admite llamar a la propiedad de la clase base. Una propiedad es en realidad un objeto invocable que se configura con la función especificada y luego reemplaza ese nombre en la clase. Esto podría significar fácilmente que no hay super función disponible.

Sin embargo, siempre puedes cambiar tu sintaxis para usar la función de propiedad ():

class Foo(object): def _getbar(self): return 5 def _setbar(self, a): print a bar = property(_getbar, _setbar) class FooBar(Foo): def _getbar(self): # return the same value # as in the base class return super(FooBar, self)._getbar() def bar(self, c): super(FooBar, self)._setbar(c) print "Something else" bar = property(_getbar, _setbar) fb = FooBar() fb.bar = 7


Super debería hacer el truco:

return super().bar

En Python 2.x necesita usar la sintaxis más detallada:

return super(FooBar, self).bar


class Base(object): def method(self): print "Base method was called" class Derived(Base): def method(self): super(Derived,self).method() print "Derived method was called" d = Derived() d.method()

(Es decir, a menos que me falta algo de su explicación)