Can't set an arbitrary attribute in an instance of an object
<p>I'm using the pygame library, it has an object pygame.Surface() that has a bunch of methods. This is what I'm trying to do:</p>

<pre><code>my_surface = pygame.Surface((5,5)) #the object requires a size to instantiate
my_surface.coords = (10,10)
</code></pre>

<p>But it throws me this error:</p>

<pre><code>Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
AttributeError: 'pygame.Surface' object has no attribute 'coords'
</code></pre>

<p>same things happen if I use</p>

<pre><code>setattr(my_surface, 'coords', (10,10))
</code></pre>

<p>instead of </p>

<pre><code>my_surface.coords = (10,10)
</code></pre>

<p>BUT if I make my own class</p>

<pre><code>class MyClass():
    pass

instance = MyClass()
instance.coords = (10,10)
</code></pre>

<p>it works like a charm.</p>

<p>I've read that it has something to do with not having a __dict__ on every instance of an object (though it was about the default python object()) which would cause objects to use too much memory, and indeed when I do</p>

<pre><code>my_surface.__dict__ #this is a pygame.Surface() object
</code></pre>

<p>it throws </p>

<pre><code>AttributeError: 'pygame.Surface' object has no attribute '__dict__'
</code></pre>

<p>while</p>

<pre><code>instance.__dict__ #this is a MyClass() object
</code></pre>

<p>returns</p>

<pre><code>{}
</code></pre>

<p>Is there any way I can modify this particular instance to accept arbitrary attributes? Currently the only workaround I can think of is to create a child class for pygame.Surface() and give it a __dict__, but obviously it's rather confusing to have to choose in advance whether or not I'll need to add arbitrary attributes for every instance of a Surface(), and and instantiating every Surface with a __dict__ defeats the whole purpose of it having no __dict__ in the first place.</p>

<p>I don't think there's a better way than subclassing <code>Surface</code> if you <em>really</em> need to be able to assign arbitrary attributes to an instance. The subclass can be empty if you don't need to add any other features (the instance <code>__dict__</code> will be created automatically).</p>

<pre><code>class MySurface(pygame.Surface):
    pass
</code></pre>

<p>However, I'm not sure you really need that ability.</p>

<p>A better design is generally to encapsulate the <code>Surface</code> object and whatever other data you have as attributes of some other object type. In Pygame you'll often use a subclass of <code>pygame.sprite.Sprite</code> to bundle a <code>Surface</code> (as the <code>image</code> attribute) with coordinates (as part of the <code>rect</code> attribute). If you have any other data you need to bundle, the <code>Sprite</code> can take it too. <code>Sprite</code> instances have a <code>__dict__</code> by default, even if you don't write your own subclass.</p>

python python-3.x