2015-07-19 2 views
2
def mainProgram(myDict): 
    methodDict = {'add': addDB(myDict, params[1], params[2]), 
        'find': findDB(myDict, params[1]), 
        'del': removeDB(myDict, params[1], params[2]), 
        'clear': clearAll(myDict)} 
    inpt = None 
    while inpt != "End": 
     inpt = input("-->") 
     params = inpt.split() 
     methodDict[params[0]] 

Вот мой код, когда я пытаюсь выполнить код, я получаю, «UnboundLocalError: локальные переменные„Титулы“ссылочные Перед назначением»Declare функция внутри словаря

Можно ли делать то, что я пытаясь сделать в python?

+0

Pls первый правильный ваша функция отступ. – Kasramvd

+0

@ Kasra. Там мы идем. Должен быть скопирован и вставлен странно. – JPHamlett

+0

что вы пытаетесь достичь? что возможно ввода/вывода? –

ответ

6

Итак, что же на самом деле происходит в

methodDict = {'add': addDB(myDict, params[1], params[2]), 
       'find': findDB(myDict, params[1]), 
       'del': removeDB(myDict, params[1], params[2]), 
       'clear': clearAll(myDict)} 

является то, что вы выполнитьaddDB и т.д., то есть, ваш methodDict будет содержать результат addDB(...params...), если бы это было бежать.

К сожалению, он не запускается, поскольку параметры не определены, когда это выполнение происходит.

Что вы хотите сделать это, хранить вызываемым в словаре и запустить его ... что-то вроде

methodDict = {'add': lambda x: addDB(myDict, x[0], x[1])} 
# and you execute with 
methodDict['add'](params) 
+0

Кажется глупо сочинять эту функцию. См. Мой ответ –

+2

@AdamSmith Я согласен. Я просто хотел показать, что вы должны иметь возможность вызова там без изменения кода. На самом деле, ваша чище и гораздо более «правильная». Я поддержал это. –

1

Это не совсем подходит, но я думаю, что лучше использовать reference чем объявить словарь.

def test(): 
    print("it works") 

dict = {"blabla" : test} 
dict["blabla"]() 
2

Вы пытаетесь составить функцию, используя аргументы, приведенные в командной строке в input строке? Вы можете сделать это с помощью lambda, хотя в этом случае у вас уже есть определенные функции, поэтому зачем беспокоиться об этом?

def main_program(dct): 
    methods = {'add': addDB, 
       'find': findDB, 
       'del': removeDB, 
       'clear': clearAll} 

    inp = input("whatever") 
    method_name, *args = inp.split() 
    try: 
     method = methods[method_name] 
    except KeyError: 
     # what do you do when the user's entry is wrong? 
    else: 
     method(dct, *args) 

Вы также можете использовать functools.partial с этим подходом, поскольку @ozgur сделал в своем замечательном ответе

from functools import partial 

def main_program(dct): 
    methods = {'add': partial(addDB, dct), 
       ...} 
    # note that this is identical in effect to 
    # # lambda *args: addDB(dct, *args) 
    ... 
    method_name, *args = inp.split() 
    method = methods[method_name] # ignoring the try/catch behavior above 
    method(*args) 
4

Вы можете использовать functools.partial функции, чтобы задержать выполнение функции, если не предусмотрены все параметры.

from functools import partial 

def add(x, y): 
    return x + y 

>>> partial_add = partial(add, 5) 
>>> partial_add(7) 
12 

Что касается вашего вопроса;

def mainProgram(myDict): 
    methodDict = {'add': partial(addDB, myDict), 
        'find': partial(findDB, myDict), 
        'del': partial(removeDB, myDict), 
        'clear': partial(clearAll, myDict)} 

    inpt = None 
    while inpt != "End": 
     inpt = input("-->") 
     params = inpt.split() 
     methodDict[params[0]](*params[1:]) 
+2

рассмотрите возможность распаковки 'inpt.split' с помощью распаковки кортежей. Это должно сделать более понятным: 'method_name, * parms = inpt.split(); methodDict [method_name] (* parms) ' –

+1

@AdamSmith, поскольку плакат не указывал, какую версию python он использует, я решил избежать такого использования распаковки значений. – ozgur