The fact you defined color
in the class's namespace (making it a class attribute) doesn't make it available in methods bodies. Names in a method (actually a function) body are resolved at function execution time, not at function definition time, and at this point the color
varibale defined in the class body has already be turned into a class attributes - they are not part of the function's non-local namespace.
Now the "proper" solution depends on what you want to achieve.
If all of your particle instance should share the same "color" value, just keep the class attribute and remove the instance one in your initializer - class attributes can be accessed directly from the instances, so self.color
will automagically resolve to type(self).color
. Note that this won't prevent you to assign per-instance color values - the class attribute is only accessed thru the instance if the instance has no attribute by that name, so setting your_particle.color = something_else
(or self.color = ...
- just the same) later in your code will still create an instance attribute and shadow the class-level one - but this is usually considered bad practice as it doesn't make the intent clear.
If you want per-instance colors, the best solution is to get rid of the class level attribute and only set the color in the initializer ie
class Particle:
# better to make this an implementation attribute
_ID = 0
@classmethod
def _next_id(cls):
cls._ID += 1
return cls._ID
def __init__(self, rect):
self.ID = self._next_id()
self.color = (255, 0, 0)
or (if you want to be able to specify the color at instantiation time):
def __init__(self, rect, color=(255, 0, 0)):
self.ID = self._next_id()
self.color = color