如何解决“ NameError:未定义名称'color'”的问题?

时间:2020-02-17 12:35:09

标签: python python-3.x

这是我的代码:

size = (1280, 850)
Win = pygame.display.set_mode(size)
class Particle:
    color = (255, 255, 0)
    ID = 0

    def __init__(self, rect):
        Particle.ID += 1
        self.color = (color)
        self.ID = Particle.ID
        self.rect = rect

    def move(self, x, y):
        self.rect.move(x, y)

    def draw(self):
        pygame.draw.rect(Win, self.color, self.rect)

    def collide(self, rect1):
        return self.rect.colliderect(rect1)

当我运行项目时,我有:“ self.color =(color) NameError:名称“ color”未定义”,但颜色已定义...它位于类“ Particle”的开头...

谢谢帮助我!

6 个答案:

答案 0 :(得分:3)

您在类的名称空间中定义了color(使其成为类属性)的事实并不使它在方法主体中可用。方法(实际上是函数)主体中的名称是在函数执行时而不是在函数定义时解析的,此时,在类主体中定义的color变量已经变成了类属性-它们是不是该函数的非本地名称空间的一部分。

现在,“适当的”解决方案取决于您要实现的目标。

如果您所有的粒子实例都应该共享相同的“颜色”值,则只需保留类属性并将其实例化到初始化中即可-类属性可以直接从实例中访问,因此self.color将自动地解析为type(self).color。请注意,这不会阻止您分配每个实例的颜色值-如果实例没有该名称的属性,则只能通过实例访问class属性,因此设置your_particle.color = something_else(或self.color = ...-相同)在您的代码的后面仍然会创建一个实例属性并遮盖该类级别的实例属性-但这通常被认为是不好的做法,因为它不能使意图明确。

如果要按实例显示颜色,最好的解决方案是摆脱类级别属性,而仅在初始化程序中设置颜色,即

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)

或(如果希望在实例化时指定颜色):

    def __init__(self, rect, color=(255, 0, 0)):
        self.ID = self._next_id()
        self.color = color

答案 1 :(得分:1)

从技术上讲:您不需要实例属性,colorID已经可用:

class Particle:
    color = (255, 255, 0)
    ID = 0

    def __init__(self, rect):
        Particle.ID += 1
        self.rect = rect

        print(self.ID)
        print(self.color)

p = Particle(None)

输出:

1
(255, 255, 0)

注意:如果您确实需要colorID作为实例变量,请使用另一个名称:

class Particle:
    color = (255, 255, 0)
    ID = 0
    def __init__(self, rect):
        Particle.ID += 1
        self.rect = rect
        self.pcolor = self.color
        self.pID = self.ID

答案 2 :(得分:0)

删除self.color = (color)行以使您的代码正常工作。

答案 3 :(得分:0)

您的color中没有变量__init__(),因此将类变量分配给实例变量是没有意义的-默认情况下它将具有它。但是你可以做类似的事情

MyParticle = Particle(some_rect)
MyParticle.color = (255, 0, 255)

答案 4 :(得分:0)

一些评论。由于将颜色定义为类变量,因此您可能不想将其重新分配为实例变量。只需将其直接与Particle.color一起使用(请参见下面的draw)。如果要跟踪ID,可以使用id(object)。不过,您可以将现有策略用于ID

class Particle:
    color = (255, 255, 0)

    def __init__(self, rect):
        self.rect = rect

    def move(self, x, y):
        self.rect.move(x, y)

    def draw(self):
        print(Particle.color, self.rect) # pygame.draw.rect

p = Particle("Rectangle dimensions")                                   
id(p)                                                                  
> 4559902608

p2 = Particle("Rectangle dimensions")
id(p2)
> 4559964496

答案 5 :(得分:-4)

我还不能发表评论。

尝试一下:

public:

   Worker(const Worker&) = delete;
   Worker& operator=(const Worker&) = delete;
   Worker(Worker&&) = default;
   Worker& operator=(Worker&&) = default;

编辑: 让我纠正,我没有您实现类的完整上下文。您必须将类初始化为对象,因为功能绘制会计算self容器中的颜色。因此,您必须创建对象,然后从该对象调用draw函数。因此,Particle.draw()将无法工作,因为未调用类初始化程序。

因此:

self.color = (color) -> self.color = color