2015-01-08 14 views
13

Tôi đang cố gắng tạo chương trình sẽ đọc trong chuỗi JSON thông qua GUI và sau đó sử dụng điều này để thực hiện các hàm bổ sung, trong trường hợp này phá vỡ một phương trình toán học. Tại thời điểm tôi gặp lỗi:Đọc chuỗi JSON | TypeError: chuỗi chỉ số phải là số nguyên

"TypeError: string indices must be integers"

và tôi không biết tại sao.

Các JSON Tôi cố gắng để đọc như sau:

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

Bạn có thể cung cấp toàn bộ stacktrace không? –

+0

Xin chào, cảm ơn bạn đã trả lời :) Trong khi chạy chương trình, cửa sổ Call Stack vẫn còn trống –

Trả lời

16

Bạn không bao giờ phân tích các chuỗi để một cuốn từ điển (object json). Thay đổi data = mtext tới: data = json.loads(mtext) Bạn cũng nên thêm global data với phương pháp readText

+0

@Rawing Bạn có nghĩa là trong mhello phải không? Nguyên nhân _getCurrentOperator đã nhận được nó theo tham số. –

+0

OK TY Sẽ chỉnh sửa. Tôi luôn sử dụng OOP nên tôi không quen thuộc với toàn cầu. –

+0

Cảm ơn bạn đã trả lời! Đã thực hiện những thay đổi này, tôi vẫn gặp phải cùng một lỗi chính xác –

4

TypeError: string indices must be integers nghĩa một nỗ lực để truy cập vào một vị trí trong một chuỗi sử dụng một chỉ số đó không phải là một số nguyên. Trong trường hợp này, mã của bạn (dòng 18) đang sử dụng chuỗi "type" làm chỉ mục. Vì đây không phải là số nguyên, ngoại lệ TypeError được nâng lên.

Dường như mã của bạn đang mong đợi data làm từ điển. Có (ít nhất) 3 vấn đề:

  1. Bạn không giải mã ("tải") chuỗi JSON. Đối với điều này, bạn nên sử dụng json.loads(data) trong chức năng readText(). Điều này sẽ trả lại từ điển mà mã của bạn mong đợi ở nơi khác.
  2. data là biến toàn cục có giá trị được khởi tạo thành một chuỗi trống (""). Bạn không thể sửa đổi biến toàn cầu trong một hàm mà không khai báo biến bằng cách sử dụng từ khóa global.
  3. Mã tạo danh sách bằng cách chắp thêm các mục liên tiếp vào danh sách đó, tuy nhiên, danh sách đó không được sử dụng ở nơi khác. Nó được in sau khi định nghĩa của _getCurrentOperator() nhưng điều này là trước khi bất kỳ xử lý đã được thực hiện, do đó nó vẫn còn trống tại thời điểm đó và [] được hiển thị. Di chuyển print(list) đến mhello() sau _getCurrentOperator(). (BTW sử dụng list như một tên biến không được khuyến cáo như thế này bóng tối các BUILTIN list)

Bạn có thể sửa đổi readText() này:

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

"Có vẻ như mã của bạn đang mong đợi dữ liệu làm từ điển." +1 – Robin

3

đôi khi bạn cần phải sử dụng json.loads một lần nữa .. điều này làm việc cho tôi ..

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

cuối cùng !! json

Các vấn đề liên quan