我读到应该避免使用exec
和eval
,除非确实需要它,所以我想知道以下情况是否是它的有效用法,如果它们不是,那么什么可以我改用了吗?
在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__
可以是Place
,Npc
等等......我知道我可以使用一堆if
,但是......这样做真的好吗?我的意思是,我似乎无法在这里看到“危险”。
答案 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)