3

我读到应该避免使用execandeval除非真的需要,所以我想知道以下情况是否是它的有效用法,如果不是,我可以用什么代替?

Npc类的方法中,我需要从Place类的实例中更改变量。像这样:

Npc.move(self,destination)

exec "%s.matrix[self.position[0]][self.position[1]] = False" % (self.place)

npc“所在”的实例self.place名称在哪里。Place执行时可能会给出,例如:

bedroom.matrix[0][0] = False

我能想到的是:在Place类上创建一个方法来做到这一点(将位置设置为False)。但这样做真的更好吗?这样我最终会得到一些只使用一次的单行函数。

我也曾经exec调用过外部方法:

def save(self):
    """
    Saves the object instance to the database.
    """
    exec "sql.routines.%s.add(self)" % (self.__type__)

__type__可以在哪里PlaceNpc等等...我知道我可以使用一堆if's,但是...这样做真的更好吗?我的意思是,我似乎看不到这里的“危险”。

4

2 回答 2

4

Place与其存储 a的字符串名称,不如存储类NPC的一个实例Place,然后直接调用该实例。

class Npc:
    def __init__(self, place):
        self.place = place

    def move(self, destination):
        self.place.matrix[self.position[0]][self.position[1]] = False        
        ...

place = SomePlace()
npc = Npc(place)
npc.move("foo")
npc.place = SomeOtherPlace()
npc.move("bar")

第二个示例几乎可以肯定也可以重新设计以排除使用,exec尽管如果没有代码的细节就无法说明如何使用sql.routines(我想它可能看起来像一个通用add方法,而不是instanceof在必要时专门用于类型)。

除非您有令人信服的理由这样做,否则我强烈建议您使用现有的 sql 库,例如sqlalchemy

于 2013-06-30T18:52:55.977 回答
2

这些都不是使用 eval 的好用例

rooms['bedroom'] = matrix
rooms['yard'] = matrix...

然后做类似的事情

rooms[self.place][self.position[0]][self.position[1]] = false

保存可能会更好

getattr(sql.routines,self.type).add(self)
于 2013-06-30T18:52:47.093 回答