2015-01-08 14 views
13

Próbuję utworzyć program, który będzie odczytywał ciąg znaków JSON za pośrednictwem interfejsu GUI, a następnie używał go do wykonywania dodatkowych funkcji, w tym przypadku dzieląc równanie matematyczne. W tej chwili pojawia się błąd:Odczytywanie łańcucha JSON | TypeError: wskaźniki łańcuchowe muszą być liczbami całkowitymi

"TypeError: string indices must be integers"

i nie mam pojęcia, dlaczego.

JSON Próbuję czytać następująco:

{ 
"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

Czy możesz podać cały stos stosu? –

+0

Witam, dziękuję za odpowiedź :) Podczas działania programu okno Call Stack pozostaje puste –

Odpowiedz

16

Nigdy są parsowania ciąg do słownika (obiekt JSON). Zmień data = mtext do: data = json.loads(mtext) Należy również dodać global data metody READTEXT

+0

@Rawing Masz na myśli w mhello prawda? Powoduje, że _getCurrentOperator pobiera ją już po parametrze. –

+0

OK TY Umożliwia edycję. Zawsze używam OOP, więc nie jestem zaznajomiony z globalnym. –

+0

Dzięki za odpowiedź! Po wprowadzeniu tych zmian nadal występuje ten sam błąd. –

4

TypeError: string indices must be integers oznacza próbę uzyskania dostępu do lokalizacji w obrębie łańcucha przy użyciu indeksu, który nie jest liczbą całkowitą. W tym przypadku twój kod (linia 18) używa indeksu "type". Ponieważ nie jest to liczba całkowita, zgłaszany jest wyjątek TypeError.

Wygląda na to, że Twój kod oczekuje, że data będzie słownikiem. Istnieją (co najmniej) 3 problemy:

  1. Nie dekodujesz ("ładowanie") ciągu JSON. W tym celu powinieneś użyć funkcji json.loads(data) w funkcji readText(). Spowoduje to zwrócenie słownika, którego twój kod oczekuje w innym miejscu.
  2. data jest zmienną globalną o wartości inicjalizowanej na pusty ciąg znaków (""). Nie można modyfikować zmiennej globalnej w funkcji bez uprzedniego zadeklarowania zmiennej za pomocą słowa kluczowego global.
  3. Kod tworzy listę, dołączając do niej kolejne elementy, jednak ta lista nie jest używana w innym miejscu. Jest drukowany po definicji _getCurrentOperator(), ale jest to przed wykonaniem jakiegokolwiek przetwarzania, dlatego w tym miejscu nadal jest puste i wyświetla się []. Przenieś print(list) do mhello() po _getCurrentOperator(). (BTW użyciu list jako nazwa zmiennej nie jest zalecane, ponieważ cienie z wbudowaną list)

Można zmienić readText() do tego:

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

"Wygląda na to, że twój kod oczekuje, że dane będą słownikiem." +1 – Robin

3

czasami trzeba ponownie użyć json.loads .. to zadziałało dla mnie ..

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

nareszcie !! json

Powiązane problemy