在不带exec/eval的字符串中调用代码,python

在不带exec/eval的字符串中调用代码,python,python,reference,eval,exec,Python,Reference,Eval,Exec,我有一段代码,当玩家试图吃东西时执行: def eat(target='object'): global current_room global locations global inventory if target in inventory: items[target]['on_eat'] #This is showing no results. else: print 'You have no ' + target +

我有一段代码,当玩家试图吃东西时执行:

def eat(target='object'):
    global current_room
    global locations
    global inventory
    if target in inventory:
        items[target]['on_eat'] #This is showing no results.
    else:
        print 'You have no ' + target + ' to eat.'
此代码用于项目(已修剪)

有没有一种有效的方法可以调用items[whatever]['on_eat'],而不用执行exec()或eval()之类的愚蠢操作?如果不是,也可以使用其他格式作为示例

在此之前,items[everyitems]['on_eat']值不是字符串,而是在代码运行后立即对每个项执行on_eat


我已经看到了许多类似问题的答案,但它们并没有处理函数唯一的参数——更确切地说,它们更像是

您可以将函数和函数参数存储为
部分

from functools import partial

items = { 
'strawberry': { 
    'weight': 1, 
    'text': 'The strawberry is red', 
    'on_eat': partial(normal_eat, 'strawberry', 'pretty good, but not as sweet as you expected') 
    }, 
'trees': { 
    'weight': 50, 
    'text': 'The trees are tall with large, leaf filled branches blocking out a majority of sunlight.', 
    'on_eat': partial(forcesay, 'Eating trees? What the hell is your problem?')
    } 

def eat(target='object'):  
    # those globals are probably not necessary
    if target in inventory:  
        items[target]['on_eat']()  #Add ()'s to call the partial
    else:  
        print 'You have no ' + target + ' to eat.'

您可以使用代码模块

def eat(target='object'):
    import code
    console = code.InteractiveConsole(locals()) # make a python interpreter with local vars
    if target in inventory:
        console.push("items[target]['on_eat']")
    else:
        print 'You have no ' + target + ' to eat.'

部分函数的另一种替代方法是编写如下项

items = {
'strawberry': {
    'weight': 1,
    'text': 'The strawberry is red',
    'on_eat': (normal_eat,('strawberry', 'pretty good, but not as sweet as you expected'))
    },
'trees': {
    'weight': 50,
    'text': 'The trees are tall with large, leaf filled branches blocking out a majority of sunlight.',
    'on_eat': (forcesay,('Eating trees? What the hell is your problem?',))
    }
}
def eat(target='object'):
    if target in inventory:
        func, args = items[target]['on_eat']
        func(*args)
    else:
        print 'You have no ' + target + ' to eat.'
这样称呼它

items = {
'strawberry': {
    'weight': 1,
    'text': 'The strawberry is red',
    'on_eat': (normal_eat,('strawberry', 'pretty good, but not as sweet as you expected'))
    },
'trees': {
    'weight': 50,
    'text': 'The trees are tall with large, leaf filled branches blocking out a majority of sunlight.',
    'on_eat': (forcesay,('Eating trees? What the hell is your problem?',))
    }
}
def eat(target='object'):
    if target in inventory:
        func, args = items[target]['on_eat']
        func(*args)
    else:
        print 'You have no ' + target + ' to eat.'

你不需要那些
global
语句,除非你重新分配它们

,这很奇怪;它起作用了。我想这是有道理的,你/有人能告诉我速度/cpu/步数是如何下降的吗?此外,为什么不在定义项之后随意执行partials,就像定义项[blah]['on_eat']值时那样较少/正常函数调用?因为在items dict的on_eat元素中创建分部时,分部实际上并不调用函数。它所做的只是捕获要调用的函数和要调用它的任何参数。当您访问分部并使用()调用它时,将调用该函数。试试这个:z=partial(min,2,4,6)什么都没有发生。现在调用z:z()返回答案2。创建分部时未调用min;仅当您以z()的形式调用分部函数时才调用它。就速度而言,它应该与调用原始函数非常接近。谢谢。另外,如果我想同时使用打印、更改当前房间、调用正常饮食、再次打印、爆炸用户扬声器等物品[“但丁地狱中的魔法运输食品”][“吃上”]执行多项操作,该怎么办。我假设我必须创建一个单独的函数来完成所有这些工作,或者只是修改数据结构来存储一个分部列表,而不仅仅是一个分部,然后逐个调用它们。这就是我在pyparsing中使用解析操作所做的。很抱歉,我错过了对象后面的结束引号