You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法为pygame.Surface对象添加新属性?

问题:为什么Pygame Surface对象无法动态添加属性?

当创建普通Python对象时,可为其分配__init__()方法中未定义的属性:

class Test:
    pass

test = Test()
test.Something = 0

但使用Pygame的Surface对象时却无法实现,代码如下:

import pygame

pygame.init()
screen = pygame.display.set_mode()
print(type(screen))

red = (255, 0, 0)
blue = (0, 0, 255)

screen.turn = 0
while True:
    if (screen.turn):
        screen.fill(blue)
    else:
        screen.fill(red)

    screen.turn = 1 - screen.turn

    pygame.event.pump()
    pygame.display.update()

运行后抛出AttributeError异常,输出如下:

pygame 2.1.2 (SDL 2.0.18, Python 3.9.13)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "/Users/armaho/Programs/Python/main.py", line 10, in <module>
    screen.turn = 0
AttributeError: 'pygame.Surface' object has no attribute 'turn'
<class 'pygame.Surface'>
解答

核心原因在于两类对象的实现机制不同:

  • 你自定义的Test类是纯Python实现的类,这类类默认会给每个实例分配__dict__属性,专门用于存储实例的动态属性,因此可以随意添加未预先定义的属性。
  • 而pygame.Surface是C扩展实现的类(属于Python的扩展类型),这类类出于性能优化或设计规范的考虑,默认不会为实例提供__dict__,自然无法动态添加新属性。只有当扩展类开发者特意在类定义中启用__dict__支持,或者实现了__setattr__方法时,才能动态添加属性。

解决思路很简单:不要试图给Surface对象附加状态,单独用变量管理你的自定义状态即可,修改后的代码示例:

import pygame

pygame.init()
screen = pygame.display.set_mode()
print(type(screen))

red = (255, 0, 0)
blue = (0, 0, 255)

turn = 0  # 单独用变量管理状态
while True:
    if turn:
        screen.fill(blue)
    else:
        screen.fill(red)

    turn = 1 - turn

    pygame.event.pump()
    pygame.display.update()

内容的提问来源于stack exchange,提问作者Armaho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 13:45:45