首页 > 解决方案 > open().read() 函数在第二次调用时返回空字符串,即使在重新打开文件后也是如此:Python

问题描述

我的代码:

def Open_Settings():
    global Configurations
    
    Settings_Window = Toplevel()
    Settings_Window.config(background = "#000014")
    Settings_Window.title("Space Shooter: Settings")
    Settings_Window.iconphoto(False, Settings_Window_Icon)
    
    Setting_Frame = Frame(Settings_Window, height = 873, width = 810, background = "#000014")
    Setting_Frame.pack()
    
    try:
        Player_1 = Image.open("Images\\Player_Space_Ship(1).png")
        Player_1 = Player_1.resize((60, 60), Image.ANTIALIAS)
        Player_1 = ImageTk.PhotoImage(Player_1)
        Player_2 = Image.open("Images\\Player_Space_Ship(2).png")
        Player_2 = Player_2.resize((60, 60), Image.ANTIALIAS)
        Player_2 = ImageTk.PhotoImage(Player_2)
        Player_3 = Image.open("Images\\Player_Space_Ship(3).png")
        Player_3 = Player_3.resize((60, 60), Image.ANTIALIAS)
        Player_3 = ImageTk.PhotoImage(Player_3)
        Enemy_1 = Image.open("Images\\Enemy_Space_Ship(1).png")
        Enemy_1 = Enemy_1.resize((60, 60), Image.ANTIALIAS)
        Enemy_1 = ImageTk.PhotoImage(Enemy_1)
        Enemy_2 = Image.open("Images\\Enemy_Space_Ship(2).png")
        Enemy_2 = Enemy_2.resize((60, 60), Image.ANTIALIAS)
        Enemy_2 = ImageTk.PhotoImage(Enemy_2)
        Enemy_3 = Image.open("Images\\Enemy_Space_Ship(3).png")
        Enemy_3 = Enemy_3.resize((60, 60), Image.ANTIALIAS)
        Enemy_3 = ImageTk.PhotoImage(Enemy_3)
        Boss_1 = Image.open("Images\\Boss_Space_Ship(1).png")
        Boss_1 = Boss_1.resize((120, 60), Image.ANTIALIAS)
        Boss_1 = ImageTk.PhotoImage(Boss_1)
        Boss_2 = Image.open("Images\\Boss_Space_Ship(2).png")
        Boss_2 = Boss_2.resize((120, 60), Image.ANTIALIAS)
        Boss_2 = ImageTk.PhotoImage(Boss_2)
    
    except Exception as Error:
        Alert.showerror("Files not Found", "Error: " + str(Error) + "\nRequired files not found at destination.")
        Settings_Window.destroy()
        return
    
    Settings_Config = Configurations
    
    Title = Label(Setting_Frame, text = "Settings", background = "#000014", foreground = "#FFFFFF", font = ("Times New Roman", 36))
    Title.place(x = 333, y = 3)
    Appear_Title = Label(Setting_Frame, text = "Appearence", background = "#000014", foreground = "#FFFFFF", font = ("Times New Roman", 30, "bold", "italic", "underline"))
    Appear_Title.place(x = 3, y = 54)
    Start_Appear_Title = Label(Setting_Frame, text = "Start Window", background = "#000014", foreground = "#FFFFFF", font = ("Times New Roman", 24, "bold", "italic"))
    Start_Appear_Title.place(x = 27, y = 108)
    Change_Obj_Col_Label = Label(Setting_Frame, text = "Change Object Colour with every Movement:", foreground = "#FFFFFF", background = "#000014", font = ("Times New Roman", 18))
    Change_Obj_Col_Label.place(x = 54, y = 153)
    Change_Obj_Col_Box = ttk.Combobox(Setting_Frame, values = ("Yes", "No"), font = ("Times New Roman", 12, "italic"), state = "readonly")
    Change_Obj_Col_Box.place(x = 567, y = 150)
    Start_Win_Bg_Label = Label(Setting_Frame, text = "Start Window Background Colour:", foreground = "#FFFFFF", background = "#000014", font = ("Times New Roman", 18))
    Start_Win_Bg_Label.place(x = 54, y = 189)
    Start_Win_Bg_Box = ttk.Combobox(Setting_Frame, values = ("Space_Blue", "Black"), font = ("Times New Roman", 12, "italic"), state = "readonly")
    Start_Win_Bg_Box.place(x = 567, y = 186)
    Game_Appear_Title = Label(Setting_Frame, text = "After Game Starts", background = "#000014", foreground = "#FFFFFF", font = ("Times New Roman", 24, "bold", "italic"))
    Game_Appear_Title.place(x = 27, y = 234)
    Player_Label = Label(Setting_Frame, text = "Player Ship Skin:", background = "#000014", foreground = "#FFFFFF", font = ("Times New Roman", 18)).place(x = 54, y = 288)
    Player_Label = Label(Setting_Frame, text = "Enemy Ship Skin:", background = "#000014", foreground = "#FFFFFF", font = ("Times New Roman", 18)).place(x = 54, y = 378)
    Player_Label = Label(Setting_Frame, text = "Boss Ship Skin:", background = "#000014", foreground = "#FFFFFF", font = ("Times New Roman", 18)).place(x = 54, y = 468)
    Player_1_Button = Button(Setting_Frame, image = Player_1)
    Player_1_Button.place(x = 261, y = 279)
    Player_2_Button = Button(Setting_Frame, image = Player_2)
    Player_2_Button.place(x = 360, y = 279)
    Player_3_Button = Button(Setting_Frame, image = Player_3)
    Player_3_Button.place(x = 459, y = 279)    
    Enemy_1_Button = Button(Setting_Frame, image = Enemy_1)
    Enemy_1_Button.place(x = 261, y = 369)
    Enemy_2_Button = Button(Setting_Frame, image = Enemy_2)
    Enemy_2_Button.place(x = 360, y = 369)
    Enemy_3_Button = Button(Setting_Frame, image = Enemy_3)
    Enemy_3_Button.place(x = 459, y = 369)
    Boss_1_Button = Button(Setting_Frame, image = Boss_1)
    Boss_1_Button.place(x = 261, y = 459)
    Boss_2_Button = Button(Setting_Frame, image = Boss_2)
    Boss_2_Button.place(x = 399.6, y = 459)
    Star_Appearence_Label = Label(Setting_Frame, text = "Star Appearence:", foreground = "#FFFFFF", background = "#000014", font = ("Times New Roman", 18))
    Star_Appearence_Label.place(x = 54, y = 540)
    Star_Appearence_Box = ttk.Combobox(Setting_Frame, values = ("No Stars", "Stars but no Movement", "Stars with Movement"), state = "readonly", font = ("Times New Roman", 12, "italic"))
    Star_Appearence_Box.place(x = 567, y = 537)
    Game_Win_Bg_Label = Label(Setting_Frame, text = "Game Window Background Colour:", foreground = "#FFFFFF", background = "#000014", font = ("Times New Roman", 18))
    Game_Win_Bg_Label.place(x = 54, y = 576)
    Game_Win_Bg_Box = ttk.Combobox(Setting_Frame, values = ("Space_Blue", "Black"), font = ("Times New Roman", 12, "italic"), state = "readonly")
    Game_Win_Bg_Box.place(x = 567, y = 576)
    Game_Func_Title = Label(Setting_Frame, text = "Game Functionings", background = "#000014", foreground = "#FFFFFF", font = ("Times New Roman", 30, "bold", "italic", "underline"))
    Game_Func_Title.place(x = 3, y = 630)
    Player_Speed_Label = Label(Setting_Frame, text = "Player Ship Speed:", foreground = "#FFFFFF", background = "#000014", font = ("Times New Roman", 18))
    Player_Speed_Label.place(x = 54, y = 690)
    Player_Speed_Box = ttk.Combobox(Setting_Frame, values = ("Low", "Medium (Recommanded)", "High"), state = "readonly", font = ("Times New Roman", 12, "italic"))
    Player_Speed_Box.place(x = 270, y = 687)
    
    def Show_Curen_Config(Widget, Character, Image_Path = None):
        if Widget == "Button":
            if Character == "Player":
                if Configurations["Appearence"]["Game"]["Player_Ship_Image"] == Image_Path:
                    return "Red"
                else: 
                    return "White"
            if Character == "Enemy":
                if Configurations["Appearence"]["Game"]["Enemy_Ship_Image"] == Image_Path:
                    return "Red"
                else: 
                    return "White"
            if Character == "Boss":
                if Configurations["Appearence"]["Game"]["Boss_Ship_Image"] == Image_Path:
                    return "Red"
                else: 
                    return "White"
        if Widget == "Combobox":
            if Character == "#000000" or Character == False or Character == "Stars but no Movement" or Character == 4:
                return 1
            elif Character == "#000014" or Character == True or Character == "No Stars" or Character == 8:
                return 0
            else: 
                return 2
    
    def Change_Settings(Character, Name, Number = 1):
        
        if Character == "Player":
            Player_1_Button.configure(background = "White")
            Player_2_Button.configure(background = "White")
            Player_3_Button.configure(background = "White")
            Name.configure(background = "Red")
            Settings_Config["Appearence"]["Game"]["Player_Ship_Image"] = "Images\\Player_Space_Ship(" + str(Number) + ").png"
        if Character == "Enemy":
            Enemy_1_Button.configure(background = "White")
            Enemy_2_Button.configure(background = "White")
            Enemy_3_Button.configure(background = "White")
            Name.configure(background = "Red")
            Settings_Config["Appearence"]["Game"]["Enemy_Ship_Image"] = "Images\\Enemy_Space_Ship(" + str(Number) + ").png"
        if Character == "Boss":
            Boss_1_Button.configure(background = "White")
            Boss_2_Button.configure(background = "White")
            Name.configure(background = "Red")
            Settings_Config["Appearence"]["Game"]["Boss_Ship_Image"] = "Images\\Boss_Space_Ship(" + str(Number) + ").png"
    
    def Save_Configures():
        if Change_Obj_Col_Box.get() == "Yes":
            Settings_Config["Appearence"]["Start"]["Change_Object_Colours"] = True
        else:
            Settings_Config["Appearence"]["Start"]["Change_Object_Colours"] = False
        if Start_Win_Bg_Box.get() == "Black":
            Settings_Config["Appearence"]["Start"]["Background_Colour"] = "#000000"
        else:
            Settings_Config["Appearence"]["Start"]["Background_Colour"] = "#000014"
        Settings_Config["Appearence"]["Game"]["Star_Appearence"] = Star_Appearence_Box.get()
        if Player_Speed_Box.get() == "High":
            Settings_Config["Game_Functionings"]["Player_Ship_Speed"] = 8
        elif Player_Speed_Box.get() == "Low":
            Settings_Config["Game_Functionings"]["Player_Ship_Speed"] = 2
        else:
            Settings_Config["Game_Functionings"]["Player_Ship_Speed"] = 4
        if Game_Win_Bg_Box.get() == "Black":
                Settings_Config["Appearence"]["Game"]["Background_Colour"] = "#000000"
        else:
            Settings_Config["Appearence"]["Game"]["Background_Colour"] = "#000014"
        print(Settings_Config)
        Configurations = Settings_Config
        Configurations = json.dumps(Configurations)
        Configuration_File = open("Space_Shooter_Configurations.json", "w")
        print(Configurations)
        print(type(Configurations))
        Configuration_File.write(Configurations)
        Show_Configs()
        
    def Set_Defaults():
        Configurations = {
            "Appearence": 
                {
                "Start": 
                    {
                    "Change_Object_Colours": True,
                    "Background_Colour": "#000014"
                },
                "Game": 
                    {
                    "Player_Ship_Image": "Images\\Player_Space_Ship(1).png",
                    "Enemy_Ship_Image": "Images\\Enemy_Space_Ship(1).png",
                    "Boss_Ship_Image": "Images\\Boss_Space_Ship(1).png",
                    "Star_Appearence": "Stars with Movement",
                    "Background_Colour": "#000014"
                }
            },
        "Game_Functionings":
            {
                "Player_Ship_Speed": 4
            }
        }
        Configurations = json.dumps(Configurations)
        Configuration_File = open("Space_Shooter_Configurations.json", "w")
        Configuration_File.write(Configurations)
        Show_Configs()
    
    def Show_Configs():
        Configuration_File = open("Space_Shooter_Configurations.json", "r") # Here
        Configuration_File.seek(0)
        Configurations = Configuration_File.read()
        if Configurations:
            print("Filled")
        else:
            print("Empty")
        Configurations = json.loads(Configurations)
        
        Player_1_Button.configure(command = lambda: Change_Settings("Player", Player_1_Button, 1), background = Show_Curen_Config("Button", "Player", "Images\\Player_Space_Ship(1).png"))
        Player_2_Button.configure(command = lambda: Change_Settings("Player", Player_2_Button, 2), background = Show_Curen_Config("Button", "Player", "Images\\Player_Space_Ship(2).png"))
        Player_3_Button.configure(command = lambda: Change_Settings("Player", Player_3_Button, 3), background = Show_Curen_Config("Button", "Player", "Images\\Player_Space_Ship(3).png"))
        Enemy_1_Button.configure(command = lambda: Change_Settings("Enemy", Enemy_1_Button, 1), background = Show_Curen_Config("Button", "Enemy", "Images\\Enemy_Space_Ship(1).png"))
        Enemy_2_Button.configure(command = lambda: Change_Settings("Enemy", Enemy_2_Button, 2), background = Show_Curen_Config("Button", "Enemy", "Images\\Enemy_Space_Ship(2).png"))
        Enemy_3_Button.configure(command = lambda: Change_Settings("Enemy", Enemy_3_Button, 3), background = Show_Curen_Config("Button", "Enemy", "Images\\Enemy_Space_Ship(3).png"))
        Boss_1_Button.configure(command = lambda: Change_Settings("Boss", Boss_1_Button, 1), background = Show_Curen_Config("Button", "Boss", "Images\\Boss_Space_Ship(1).png"))
        Boss_2_Button.configure(command = lambda: Change_Settings("Boss", Boss_2_Button, 2), background = Show_Curen_Config("Button", "Boss", "Images\\Boss_Space_Ship(2).png"))
        Start_Win_Bg_Box.current(Show_Curen_Config("Combobox", Configurations["Appearence"]["Start"]["Background_Colour"]))
        Star_Appearence_Box.current(Show_Curen_Config("Combobox", Configurations["Appearence"]["Game"]["Star_Appearence"]))
        Game_Win_Bg_Box.current(Show_Curen_Config("Combobox", Configurations["Appearence"]["Game"]["Background_Colour"]))
        Player_Speed_Box.current(Show_Curen_Config("Combobox", Configurations["Game_Functionings"]["Player_Ship_Speed"]))
        Change_Obj_Col_Box.current(Show_Curen_Config("Combobox", Configurations["Appearence"]["Start"]["Change_Object_Colours"]))
        
    Show_Configs()
    
    Settings_Window.bind("<Control-s>", lambda event: Save_Configures())
    Settings_Window.bind("<Control-d>", lambda event: Set_Defaults())
    
    Settings_Window.mainloop()

好的,这是我的一段代码(因为我认为它不会影响我的问题),所以我的问题是当Show_Config()第一次调用该函数时,它可以正常工作,但第二次调用时(按 Ctrl-s/Ctrl-d 后),open("Space_Shooter_Configurations.json", "r").read()返回空字符串,导致Configurations = json.loads(Configurations)行错误。

我在执行 if-else-print 调试后才知道它,这最终让我明白第二次,Configurations 变量被分配为一个空字符串。

如您所见,我尝试Configuration_File.seek(0)了方法以及重新打开文件,但没有帮助。

版本:Python 3.8.6

IDE:Visual Studio 代码

操作系统:Windows 7(32 位)

标签: pythonpython-3.xtkinter

解决方案


Start_Game在绑定中使用引用全局名称空间中的某些内容,但您应该引用它self

没有理由尝试通过引用全局命名空间中的变量名来调用同一类中的方法。

简而言之:

这个:

    Main_Frame.bind("<Button-1>", self.Start_Game_Event)
    Main_Frame.bind("<F1>", Start_Game.Show_Info)
    Main_Frame.bind("<F2>", Start_Game.Info_About)
    Main_Frame.bind("<F3>", Start_Game.Info_Game_Play)

应该是这样的:

    Main_Frame.bind("<Button-1>", self.Start_Game_Event)
    Main_Frame.bind("<F1>", self.Show_Info)
    Main_Frame.bind("<F2>", self.Info_About)
    Main_Frame.bind("<F3>", self.Info_Game_Play)

这一切都表明您应该研究 PEP8 Python 标准。这将有助于清理您的代码。接下来我会这样做,import tkinter as tk而不是from tkinter import *这样做将帮助您防止错误地覆盖现有函数/变量。


推荐阅读