2012-05-30 6 views
17

Tengo un problema realmente extraño con Python super() y herencia y propiedades. En primer lugar, el código:Python super y configuración de la clase primaria propiedad

#!/usr/bin/env python3 

import pyglet 
import pygame 

class Sprite(pyglet.sprite.Sprite): 

    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     self.rect = pygame.Rect(0, 0, self.width, self.height) 
     self.rect.center = self.x, self.y 

    @property 
    def x(self): 
     return super().x 

    @x.setter 
    def x(self, value): 
     super(Sprite, self.__class__).x.fset(self, value) 
     self.rect.centerx = value 

    @property 
    def y(self): 
     return super().y 

    @y.setter 
    def y(self, value): 
     super(Sprite, self.__class__).y.fset(self, value) 
     self.rect.centery = value 

Esto funciona bien. Sin embargo, lo que yo quiero (lo que parece a mí Pythonic)

#super(Sprite, self.__class__).x.fset(self, value) 
super().x = value 

no funciona a pesar de que

super().x 

consigue la multa de valor. x en este caso es una propiedad de la superclase con fset y fget definidos. Entonces, ¿por qué no funciona?

Respuesta

15

Estaba tratando de encontrar el lenguaje correcto para respaldar por qué este comportamiento es el correcto, para no darle una respuesta "porque es justo" ... Parece que esta pregunta se ha formulado más de una vez, y que se reduce al comportamiento de super(). Puede ver una discusión de 2010 sobre este comportamiento exacto aquí: http://mail.python.org/pipermail/python-dev/2010-April/099672.html

En última instancia, realmente solo se reduce a las llamadas a super() que solo le permiten acceder a getters directamente, y no a los setters. Se debe acceder a los Setters a través del o __set__(). Probablemente sea más fácil explicarlo ya que la funcionalidad "super() simplemente no lo admite". Resolverá la funcionalidad de propiedad de una operación "get", no la del setter en una asignación con zurdos, en la operación "set" (de ahí la llamada al método). Como puede ver a partir de la fecha de este hilo de discusión, obviamente ha sido así desde la introducción de super().

Quizás otra persona tenga un motivo más específicamente técnico, pero francamente no estoy seguro de que importe. Si no es compatible, esa es una razón bastante buena.

+6

He archivado un error: http://bugs.python.org/issue14965 Espero que esto se resuelva pronto, por lo que esta pregunta ya no es relevante. – darkfeline

+0

"no es compatible ... una razón bastante buena" suena como "porque simplemente es". – simonzack

+0

@simonzack - Dije que estaba * intentando * no dar ese tipo de respuesta y explicar lo más posible sobre su funcionalidad. – jdi

Cuestiones relacionadas