Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在循环中添加同一类的新对象_Python_Class_Object_Python 3.x_Pygame - Fatal编程技术网

Python 在循环中添加同一类的新对象

Python 在循环中添加同一类的新对象,python,class,object,python-3.x,pygame,Python,Class,Object,Python 3.x,Pygame,我不确定标题是否给出了最好的描述。但这是我的问题。 我有一个班叫“Ball”。 每个球都有自己的宽度、半径和颜色。 当我在循环之前添加我自己的球时,我的代码工作得很好 例如:Ball 1=Ball()。。。。ball2=Ball() 我正在使用pygame,我想要的是,每当我按下“空格”键时,它都会添加另一个具有自己特点的球。我有它,所以它随机给出一个宽度,半径和颜色。 这是我的密码: BLACK = (0,0,0) WHITE = (255, 255, 255) BLUE = (0, 0, 2

我不确定标题是否给出了最好的描述。但这是我的问题。 我有一个班叫“Ball”。 每个球都有自己的宽度、半径和颜色。 当我在循环之前添加我自己的球时,我的代码工作得很好 例如:Ball 1=Ball()。。。。ball2=Ball() 我正在使用pygame,我想要的是,每当我按下“空格”键时,它都会添加另一个具有自己特点的球。我有它,所以它随机给出一个宽度,半径和颜色。 这是我的密码:

BLACK = (0,0,0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

fps = 30

color_list = [BLACK, BLUE, GREEN, RED]

col = None
siz = None
wit = None
posx = None
posy = None
ball = None


class Ball:

    ballCount = 0

    def __init__(self):
        Ball.ballCount +=1
        self.col = random.choice(color_list)
        self.siz = random.randint(20, 80)
        self.wit = random.randint(1, 3)
        self.posx = random.randint(self.siz, width-self.siz)
        self.posy = random.randint(self.siz, height-self.siz)

    def blitball(self):
        pygame.draw.circle(screen, self.col, (self.posx, self.posy),self.siz, self.wit)


    def move(self):
        self.posx+=1



ball2 = Ball()
ball1 = Ball()
ball3 = Ball()

while True:

    amount = 0



    event = pygame.event.poll()
    keys = pygame.key.get_pressed()

    if event.type == QUIT:
        pygame.quit()
        sys.exit()

    if keys[K_q]:
        pygame.quit()
        sys.exit()

    #############################################################

    if keys[K_SPACE]:
        eval("ball"+str(Ball.ballCount+1)) = Ball()

    #############################################################

    screen.fill(WHITE)

    for r in range(Ball.ballCount):
        amount+=1
        eval("ball"+str(amount)).move()
        eval("ball"+str(amount)).blitball()


    pygame.time.wait(int(1000/fps))

    pygame.display.update()
使用了范围内r的
(Ball.ballCount):
,因此我不必为每个球键入函数。这很好用。如果你知道更简单的方法,请告诉我

因此,我需要补充的是:

if keys[K_SPACE]:  
    #add another ball, ball3, ball4,..etc. 
如果这意味着要更改我的一些代码,请随时告诉我,甚至你自己也可以这样做。 感谢您提前回复。(我的问题在标签中)


丹尼斯

将你的球储存在一个列表中,并在那里采取行动

# starting three balls
balls = [Ball(),Ball(),Ball()]

while True:
    amount = 0

    event = pygame.event.poll()
    keys = pygame.key.get_pressed()

    if event.type == QUIT:
        pygame.quit()
        sys.exit()

    if keys[K_q]:
        pygame.quit()
        sys.exit()

    #############################################################

    if keys[K_SPACE]:
        balls.append(Ball())

    #############################################################

    screen.fill(WHITE)

    for ball_in_play in balls:
        ball_in_play.move()
        ball_in_play.blitball()


    pygame.time.wait(int(1000/fps))

    pygame.display.update()

您几乎不想按名称创建新变量

而且,即使在极少数情况下,您也几乎不想使用
eval
exec
来执行

而且,即使您确实希望使用
eval
exec
,您也几乎不希望将它们与默认的
局部变量
/
全局变量
一起使用

但是,让我们先看看为什么您的代码不能工作,然后看看如何做得更好

eval("ball"+str(Ball.ballCount+1)) = Ball()
您正在生成一个字符串,如
“ball4”
,然后调用
eval
。毫不奇怪,它的计算结果是字符串
“ball4”
。然后,您试图将一个新值(新构造的
Ball
实例)分配给该字符串,而不是一个变量,这显然是行不通的。(事实上,我猜你会因为试图分配给函数调用而得到一个
SyntaxError
,甚至在计算任何东西之前。)

要解决这个问题,您必须将整个内容放入
eval

eval("ball"+str(Ball.ballCount+1) + " = Ball()")
但这是行不通的,因为
eval
只适用于表达式,而不适用于语句。对于语句,您需要
exec

exec("ball"+str(Ball.ballCount+1) + " = Ball()")
这将消除你的错误

但让我们看看创建
ball4
变量的正确方法:

locals()["ball" + str(Ball.ballCount+1)] = Ball()
更简单,更难出错

但是,一旦你看到了这一点,当你可以使用任何你想要的名字时,为什么还要麻烦使用
locals()
作为
dict

my_balls["ball" + str(Ball.ballCount+1)] = Ball()
而且,一旦完成此操作,您就不需要在每个球上都加上“ball”前缀:

my_balls[Ball.ballCount+1] = Ball()
在这一点上,您可能会意识到,您的键只是自然数,这意味着您只是在用一个
dict
模拟一个
列表,所以您最好只制作一个
my\u balls
列表

然后,你不再需要
球。球数
了,它只是
len(我的球)

那么,使用
eval
exec
有什么不好呢

嗯,它的效率较低,它使您的代码更难调试(并在交互式终端中进行实验),而且它打开了巨大的安全漏洞(想象一下,您向用户询问下一个球号,他给了您“3;os.system('rm-rf/');",然后您尝试执行
exec(“ball”+user\u input\u string+“=ball()”)

但所有这些都比不上这样一个事实:它使代码更难阅读。比较:

eval("ball"+str(amount)).move()

balls[amount].move()

您已经使用了列表,因此应该了解它们。为什么不使用它们呢?这里似乎更像是一个设计问题-你试图让球做两件事-代表一个球对象,但也要跟踪所有其他球对象。如果您将它们作为两个独立的关注点来处理,您的设计似乎会简单得多;球和球本身的列表。+1用于显示代码,包括为什么
列表
使循环变得更好。非常感谢,从现在开始我将这样做,效果非常好!!非常感谢你的回答。虽然我认为Paul Seeb展示了一种出色的方式来完成我想做的事情,但我很高兴现在我对Eval和Exec有了更好的理解,对于我未来的一些项目,这个答案应该对我有很大的帮助。我选择了Paul Seebs答案,因为这是我将在代码中使用的答案,但您的答案同样有用,这是一个艰难的决定。非常感谢。