Подтвердить что ты не робот

Python super и установка свойства родительского класса

У меня очень странная проблема с Python super() и наследованием и свойствами. Во-первых, код:

#!/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

Это прекрасно работает. Однако, что я хочу (что мне кажется Pythonic)

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

не работает, хотя

super().x

получает значение штраф. x в этом случае является свойством суперкласса с определенными как fset, так и fget. Так почему же он не работает?

4b9b3361

Ответ 1

Я пытался найти правильный язык, чтобы поддержать, почему это поведение так оно и есть, чтобы не дать вам "потому что это просто" ответ... Но, похоже, этот вопрос задан больше, чем один раз и что он сводится к поведению super(). Вы можете увидеть дискуссию 2010 года об этом точном поведении здесь: http://mail.python.org/pipermail/python-dev/2010-April/099672.html

В конечном счете, это действительно сводится к вызовам super(), позволяющим напрямую обращаться к getters, а не к сеттерам. Доступ к сеттерам можно получить через fset() или __set__(). Вероятно, это проще всего объяснить, поскольку функция super() просто не поддерживает его ". Он будет разрешать функциональные возможности операции" получить ", а не сеттер в назначении левой руки, в" заданной" операции (следовательно, вызов метода fset()). Как вы можете видеть с даты этой дискуссии, очевидно, что это произошло с момента введения super().

Возможно, у кого-то есть более конкретная техническая причина, но, честно говоря, я не уверен, что это даже имеет значение. Если его не поддерживать, это довольно хорошая причина.