2015-01-08 4 views
13

Я пытаюсь создать программу, которая будет считываться в строке JSON через GUI, а затем использовать ее для выполнения дополнительных функций, в этом случае разбивая математическое уравнение. В настоящий момент я получаю сообщение об ошибке:Чтение строки JSON | TypeError: строковые индексы должны быть целыми числами

"TypeError: string indices must be integers"

и я понятия не имею, почему.

JSON Я пытаюсь читать следующим образом:

{ 
"rightArgument":{ 
"cell":"C18", 
"value":9.5, 
"type":"cell" 
}, 
"leftArgument":{ 
"rightArgument":{ 
"cell":"C3", 
"value":135, 
"type":"cell" 
}, 
"leftArgument":{ 
"rightArgument":{ 
"cell":"C4", 
"value":125, 
"type":"cell" 
}, 
"leftArgument":{ 
"cell":"C5", 
"value":106, 
"type":"cell" 
}, 
"type":"operation", 
"operator":"*" 
}, 
"type":"operation", 
"operator":"+" 
}, 
"type":"operation", 
"operator":"+" 
} 
import json 
import tkinter 
from tkinter import * 

data = "" 
list = [] 

def readText(): 
    mtext="" 
    mtext = strJson.get() 
    mlabel2 = Label(myGui,text=mtext).place(x=180,y=200) 
    data = mtext 

def mhello(): 
    _getCurrentOperator(data) 

def _getCurrentOperator(data): 
    if data["type"] == "operation": 

     _getCurrentOperator(data["rightArgument"])   
     _getCurrentOperator(data["leftArgument"]) 
     list.append(data["operator"]) 
    elif data["type"] == "group": 
     _getCurrentOperator(data["argument"]) 
    elif data["type"] == "function": 
     list.append(data["name"]) # TODO do something with arguments 
     for i in range(len(data["arguments"])): 
      _getCurrentOperator(data["arguments"][i]) 
    else: 
     if (data["value"]) == '': 
      list.append(data["cell"]) 
     else: 
      list.append(data["value"]) 

print(list) 

myGui = Tk() 
strJson = StringVar() 


myGui.title("Simple Gui") 
myGui.geometry("400x300") 

label = Label(text = 'Welcome!').place(x=170,y=40) 
btnStart = Button(myGui,text='Start',command=mhello).place(x=210,y=260) 
btnRead = Button(myGui,text='Read text',command=readText).place(x=210,y=200) 
txtEntry = Entry(myGui, textvariable=strJson).place(x=150,y=160) 
btnOptions = Button(myGui, text = "Options").place(x=150,y=260) 

myGui.mainloop() 
+0

Не могли бы вы дать весь стек? –

+0

Привет, спасибо за ответ :) Во время запуска программы окно вызова стека остается пустым –

ответ

16

Вы никогда не разборе строки в словаре (объект JSON). Изменение data = mtext на: data = json.loads(mtext) Вы должны также добавить global data методу READTEXT

+0

@Rawing Вы имеете в виду в mhello? Причина _getCurrentOperator уже получает его по параметру. –

+0

OK TY Будет редактировать. Я всегда использую ООП, поэтому я не знаком с глобальным. –

+0

Спасибо за ответ! Сделав эти изменения, я все еще испытываю ту же ошибку –

4

TypeError: string indices must be integers означает попытку доступа местоположение в пределах строки, используя индекс, который не является целым числом. В этом случае ваш код (строка 18) использует строку "type" в качестве индекса. Поскольку это не целое число, возникает исключение TypeError.

Кажется, что ваш код ожидает, что data станет словарем. Есть (по крайней мере) 3 проблемы:

  1. Вы не декодируете («загружаете») строку JSON. Для этого вы должны использовать json.loads(data) в функции readText(). Это вернет словарь, который ваш код ожидает в другом месте.
  2. data - глобальная переменная со значением, инициализированным пустой строкой (""). Вы не можете изменить глобальную переменную внутри функции без предварительного объявления переменной с использованием ключевого слова global.
  3. Код строит список, добавляя к нему последовательные элементы, однако этот список не используется в другом месте. Он печатается после определения _getCurrentOperator(), но это до того, как была выполнена какая-либо обработка, поэтому в этой точке все еще пусто, и отображается []. Переместить print(list) в mhello() после _getCurrentOperator(). (КСТАТИ, используя list как имя переменной не рекомендуется, так как это тени встроенную list)

Вы можете пересмотреть readText() к этому:

def readText(): 
    global data 
    mtext="" 
    mtext = strJson.get() 
    mlabel2 = Label(myGui,text=mtext).place(x=180,y=200) 
    data = json.loads(mtext) 
+0

«Кажется, ваш код ожидает, что данные станут словарем». +1 – Robin

3

иногда вам нужно снова использовать json.loads .. это сработало для меня ..

jsonn_forSaleSummary_string = json.loads(forSaleSummary) //still string 
jsonn_forSaleSummary  = json.loads(jsonn_forSaleSummary_string) 

окончательно !! json

Смежные вопросы