2015-01-08 28 views
13

Sto provando a creare un programma che leggerà in una stringa JSON attraverso la GUI e quindi usarlo per eseguire funzioni aggiuntive, in questo caso scomporre un'equazione matematica. Al momento sto ottenendo l'errore:Lettura di una stringa JSON | TypeError: gli indici stringa devono essere numeri interi

"TypeError: string indices must be integers"

e non ho idea del perché.

Il JSON che sto cercando di leggere è il seguente:

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

Potresti dare l'intero stacktrace? –

+0

Ciao, grazie per la risposta :) Durante l'esecuzione del programma, la finestra Stack chiamate rimane vuota –

risposta

16

non siete mai parsing della stringa a un dizionario (oggetto JSON). Cambia data = mtext a: data = json.loads(mtext) Si dovrebbe anche aggiungere global data al metodo ReadText

+0

@Rawing Intendi in mhello giusto? Causa _getCurrentOperator lo ottiene già per parametro. –

+0

OK TY Modifica. Uso sempre OOP, quindi non ho familiarità con il mondo. –

+0

Grazie per la risposta! Dopo aver apportato queste modifiche, sto ancora sperimentando lo stesso identico errore –

4

TypeError: string indices must be integers significa un tentativo di accedere a una posizione all'interno di una stringa utilizzando un indice che non è un numero intero. In questo caso il tuo codice (riga 18) utilizza la stringa "type" come indice. Poiché questo non è un numero intero, viene sollevata un'eccezione TypeError.

Sembra che il tuo codice si aspetti che data sia un dizionario. Ci sono (almeno) 3 problemi:

  1. Non sei decodifica ("carico") la stringa JSON. Per questo è necessario utilizzare json.loads(data) nella funzione readText(). Ciò restituirà il dizionario che il tuo codice si aspetta altrove.
  2. data è una variabile globale con valore inizializzato su una stringa vuota (""). Non è possibile modificare una variabile globale all'interno di una funzione senza prima dichiarare la variabile utilizzando la parola chiave global.
  3. Il codice crea un elenco aggiungendovi elementi successivi, tuttavia tale elenco non viene utilizzato altrove. Viene stampato dopo la definizione di _getCurrentOperator() ma questo è prima che sia stata eseguita qualsiasi elaborazione, quindi è ancora vuoto in quel punto e viene visualizzato []. Spostare print(list) a mhello() dopo il _getCurrentOperator(). (BTW utilizzando list come un nome di variabile non è consigliato in quanto questo ombre il comando incorporato list)

È possibile rivedere readText() a questo:

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

"Sembra che il tuo codice si aspetti che i dati siano un dizionario." +1 – Robin

3

A volte è necessario utilizzare nuovamente json.loads .. questo ha funzionato per me ..

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

finalmente !! json

Problemi correlati