[英]Python super and setting parent class property
我在 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 的超類的屬性。 那為什么不起作用呢?
我試圖找到正確的語言來支持為什么這種行為是這樣的,以免給你一個“因為它就是”的答案......但似乎這個問題已經被問過不止一次了,而且它歸結為super()
的行為。 您可以在此處查看 2010 年有關此確切行為的討論: http : //mail.python.org/pipermail/python-dev/2010-April/099672.html
最終,它確實歸結為 super() 調用,只允許您直接訪問 getter,而不是 setter。 Setter 必須通過fset()
或__set__()
。 最簡單的解釋可能是“super() 功能不支持它”。 它將在“set”操作(因此調用fset()
方法)中解析“get”操作的屬性功能,而不是左手賦值中的 setter。 正如您從本討論線程的日期中看到的那樣,自super()
引入以來,顯然就是這種方式。
也許其他人有更具體的技術原因,但坦率地說,我不確定這是否重要。 如果它不支持,那幾乎是一個足夠好的理由。
super(type(self), type(self)).setter.fset(self, value)
是一種常見的解決方法,但是它不能很好地處理多重繼承,這可能會改變 mro。
試試我的解決方案 duper(下面的鏈接): duper(super()).setter = value
https://gist.github.com/willrazen/bef3fcb26a83dffb6692e5e10d3e67ac
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.