关于exec的用法

时间:2013-06-30 18:33:14

标签: python

我读到应该避免使用execeval,除非确实需要它,所以我想知道以下情况是否是它的有效用法,如果它们不是,那么什么可以我改用了吗?

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

Npc.move(self,destination)

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

其中self.place是npc“是”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,但是......这样做真的好吗?我的意思是,我似乎无法在这里看到“危险”。

2 个答案:

答案 0 :(得分:4)

而不是在Place中存储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代码的详细信息(我想它可能看起来像一个通用的{{}}是不可能的。 {1}}方法,而不是在必要时使用add来专门处理类型。

除非你有令人信服的理由,否则我强烈建议使用现有的SQL库,例如sqlalchemy

答案 1 :(得分:2)

这些都不是使用eval的好用例,第一个可能会更好bt有房间对象

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

然后执行类似

的操作
rooms[self.place][self.position[0]][self.position[1]] = false

保存可以更好

getattr(sql.routines,self.type).add(self)