替代eval来创建可以处理多个变量的通用函数

时间:2014-07-22 16:49:06

标签: python eval

对于我正在创建的一组游戏,我有一行代码,只允许回答一次问题。如果已经回答,则会为玩家的分数添加分数(下面的代码位于检查答案的if函数内),然后关闭再次回答问题的能力。这是我目前正在使用的代码:

while self.game1_question1_not_answered:
    self.game1_player1_score += self.score_increment
    self.game1_question1_not_answered = False`

我想在代码中使用'game1'作为通用标识符,可用于识别我正在创建的多个游戏中的任何一个。我尝试使用一个名为game_name的变量(例如,game_name = game1),并使用eval函数将变量插入到代码中但尚未使代码生效。另外,我意识到eval功能有一些安全问题。我可以使用什么功能来实现这个功能?我尝试过的代码不起作用如下:

while eval('self.' + game_name + 'question1_not_answered'):
    eval('self.' + game_name + 'player1_score') += self.score_increment
    eval('self.' + game_name + 'question1_not_answered') = False

我可以使用另一个函数而不是eval来使其工作吗?

3 个答案:

答案 0 :(得分:2)

您应该使用dict代替。这将允许您创建动态命名的变量,以存储该信息。

self.game_dict = {}
self.game_dict[game_name + 'question1_not_answered'] = True

然后你可以像上面那样修改它,并以几种方式访问​​它:

>>> game_obj.game_dict.get(game_name + 'question1_not_answered')
True
>>> game_obj.game_dict[game_name + 'question1_not_answered']
True

但正如jonrsharpe所说,你的变量名不应该包含数据。最好的解决方案是制作多个游戏对象,每个对象都有question1_not_answered等变量。然后,如果需要,将所有这些对象分配给变量,在这种情况下为self

答案 1 :(得分:1)

我实际上是关注@ jonrsharpe的评论,但如果你真的需要在一个实例中使用它们,你可以使用getattrsetattr内置:

     game_name = "game1"
     question1_na_line = "{}_question1_not_answered"
     player1_sc_line = "{}_player1_score"

     question1_na = question1_na_line.format(game_name)
     player1_sc = player1_sc_line.format(game_name)
     while getattr(self, question1_na):
         setattr(self,
                 player1_sc,
                 getattr(self, player1_sc) + self.score_increment)
         setattr(self, question1_na, False)

答案 2 :(得分:0)

按名称访问属性的常用方法是getattr(obj, name)函数。现在考虑到你描述的更具体的问题,我认为你最好使用dict(或dicts等词典)存储你的游戏状态(分数等)。