簡體   English   中英

在沒有exec / eval,python的字符串中調用代碼

[英]Calling code in a string without exec/eval, python

我有這個代碼,當玩家嘗試吃東西時執行:

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 = {
'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?')"
    }
}

是否有一種有效的方式來調用項目[whatever] ['on_eat']而不做像exec()或eval()那樣愚蠢的事情? 如果沒有,作為示例的替代格式也將被理解。

在此之前,[everyitems] ['on_eat']項的值不是字符串,但是一旦代碼運行,它就會為每個項執行on_eat。

我已經看到了類似問題的許多答案,但他們沒有處理獨特函數的論證 - 更好地說,他們更喜歡這個

您可以將函數和函數參數存儲為partial

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.'

除非您要重新分配它們,否則您不需要那些global聲明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM