2010-08-11 12 views
5

tôi có mã này để thực thi khi một cầu thủ cố gắng ăn một cái gì đó:Mã số điện thoại trong một chuỗi mà không exec/eval, trăn

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

và mã này cho các hạng mục (tỉa)

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

Có cách nào hợp lệ gọi các mục [bất cứ điều gì] ['on_eat'] mà không làm điều gì đó ngớ ngẩn như exec() hoặc eval()? Nếu không, định dạng thay thế làm ví dụ cũng sẽ được đánh giá cao.

Trước khi các mục [everyitems] ['on_eat'] giá trị không phải là chuỗi, nhưng điều đó thực thi on_eat cho mỗi mục ngay khi mã được chạy.

Tôi đã thấy nhiều câu trả lời cho những câu hỏi tương tự, nhưng họ không đối phó với các đối số cho các chức năng unique- đặt tốt hơn đó, họ giống như this

Trả lời

6

Bạn có thể lưu trữ chức năng và chức năng của bạn lập luận như một 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.' 
+0

Đó là lẻ; Nó hoạt động. Vâng, tôi cho rằng nó có ý nghĩa, bạn có thể/ai đó cho tôi biết làm thế nào điều này đi xuống tốc độ/CPU/bước khôn ngoan? Ngoài ra, tại sao các partials chỉ thực hiện một cách ngẫu nhiên khi các mục được xác định như khi các mục [blah] ['on_eat'] có giá trị "" ít hơn/các cuộc gọi hàm bình thường? –

+0

Bởi vì một phần không thực sự * gọi * chức năng khi một phần được tạo ra trong các yếu tố on_eat của dict mục của bạn. Tất cả những gì nó làm là nắm bắt chức năng được gọi và bất kỳ đối số nào để gọi nó. Hàm này được gọi khi bạn truy cập một phần và gọi nó bằng(). Hãy thử điều này: z = một phần (min, 2, 4, 6) Không có gì xảy ra. Bây giờ gọi z: z() Bạn lấy lại câu trả lời 2. phút không được gọi khi phần được tạo ra; nó chỉ được gọi khi bạn gọi một phần là z(). Speedwise, nó phải được khá gần giống như chỉ cần gọi chức năng ban đầu. – PaulMcG

+0

Cảm ơn. Ngoài ra, nếu tôi muốn làm nhiều thứ cùng một lúc với các mục ['thực phẩm vận chuyển huyền diệu từ Dante \' Inferno '] [' on_eat '] in, thay đổi current_room, gọi normal_eat, in lại, phát nổ người dùng, vv. Tôi cho rằng tôi sẽ phải thực hiện một chức năng riêng biệt để thực hiện tất cả điều này? –

1

bạn có thể sử dụng các mô-đun mã

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

xin lỗi tôi đã bỏ lỡ một trích dẫn kết thúc sau đối tượng – user250418

+2

sau đó chỉnh sửa nó! – aaronasterling

0

Một thay thế cho chức năng một phần là viết mục Lik e này

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?',)) 
    } 
} 

và gọi nó như thế này

def eat(target='object'): 
    if target in inventory: 
     func, args = items[target]['on_eat'] 
     func(*args) 
    else: 
     print 'You have no ' + target + ' to eat.' 

Bạn không cần những global báo cáo có trừ khi bạn sẽ được giao lại