【问题标题】:Python super and setting parent class propertyPython super 和设置父类属性
【发布时间】:2012-06-04 08:08:10
【问题描述】:

我在 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 的超类的属性。那么为什么它不起作用呢?

【问题讨论】:

    标签: python super


    【解决方案1】:

    我试图找到正确的语言来支持为什么这种行为是这样的,以免给你一个“因为它只是”的答案......但似乎这个问题已经被问到超过一次,归结为super() 的行为。您可以在此处查看 2010 年有关此确切行为的讨论:http://mail.python.org/pipermail/python-dev/2010-April/099672.html

    最终,它实际上只是归结为 super() 调用,只允许您直接访问 getter,而不是 setter。必须通过fset()__set__() 访问设置器。可能最简单的解释是“super() 功能不支持它”。它将在“set”操作中解析“get”操作的属性功能,而不是左手赋值中的setter(因此fset()方法调用)。从这个讨论帖的日期可以看出,自从super() 引入以来,显然就是这样。

    也许其他人有更具体的技术原因,但坦率地说,我不确定这是否重要。如果它不被支持,那就足够了。

    【讨论】:

    • 我已经提交了一个错误:bugs.python.org/issue14965 希望这个问题很快得到解决,所以这个问题不再相关。
    • “它不支持......一个足够好的理由”听起来像“因为它就是这样”。
    • @simonzack - 我确实说过我是试图不给出那样的答案并尽可能解释它的功能。
    • 哦,我没有看到 OP 说“这很好用。但是”,谢谢!
    • @ErikAronesty:OP 已经做到了:super(self.__class__, self.__class__).x.fset(self, value)
    【解决方案2】:

    super(type(self), type(self)).setter.fset(self, value) 是一种常见的解决方法,但它不适用于多重继承,这可能会改变 mro。

    试试我的解决方案骗子(下面的链接):duper(super()).setter = value

    https://gist.github.com/willrazen/bef3fcb26a83dffb6692e5e10d3e67ac

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-17
      • 2011-06-16
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 2013-04-06
      • 2021-05-24
      相关资源
      最近更新 更多