无法在对象的实例中设置任意属性

时间:2016-09-08 07:11:42

标签: python python-3.x

我正在使用pygame库,它有一个对象pygame.Surface(),它有一堆方法。这就是我想要做的事情:

my_surface = pygame.Surface((5,5)) #the object requires a size to instantiate
my_surface.coords = (10,10)

但是它让我想到了这个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'pygame.Surface' object has no attribute 'coords'
如果我使用

,也会发生同样的事情
setattr(my_surface, 'coords', (10,10))

而不是

my_surface.coords = (10,10)

但如果我自己上课

class MyClass():
    pass

instance = MyClass()
instance.coords = (10,10)

它就像一个魅力。

我已经读过它与某个对象的每个实例都没有__dict__有关(虽然它是关于默认的python对象())会导致对象使用太多的内存,事实上当我做

my_surface.__dict__ #this is a pygame.Surface() object

它抛出

AttributeError: 'pygame.Surface' object has no attribute '__dict__'

,而

instance.__dict__ #this is a MyClass() object

返回

{}

有什么方法可以修改这个特定的实例来接受任意属性?目前我能想到的唯一解决方法是为pygame.Surface()创建一个子类并给它一个__dict__,但显然我必须提前选择是否需要为每个添加任意属性而相当混乱Surface()的实例,并且使用__dict__实例化每个Surface会使第一个地方没有__dict__的整个目的失败。

1 个答案:

答案 0 :(得分:1)

如果确实需要能够为实例分配任意属性,我认为这不如继承Surface更好。如果您不需要添加任何其他功能,则子类可以为空(将自动创建实例__dict__)。

class MySurface(pygame.Surface):
    pass

但是,我不确定你真的需要这种能力。

更好的设计通常是将Surface对象和您拥有的任何其他数据封装为某些其他对象类型的属性。在Pygame中,您经常使用pygame.sprite.Sprite的子类将Surface(作为image属性)与坐标(作为rect属性的一部分)捆绑在一起。如果您需要捆绑任何其他数据,Sprite也可以使用它。默认情况下,Sprite个实例的__dict__GET https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/Fabrikam-Fiber-Git/_apis/build/builds/391/logs?api-version=2.0 ,即使您没有编写自己的子类。