Pickle在加载时引发AttributeError

时间:2018-11-28 17:33:54

标签: python class tkinter pickle

我有这个Editor课:

from BotEngine.Editor.BotClass import *
import pickle
import os

class Editor():

    def createBot(self, name = '', token = ''):
        if name == '':
            name = input('Enter bot name: ')

        if token == '':
            token = input('Enter bot token: ')

        self.CurrentBot = ChatBot(name, token, self) # Creating bot

        self.saveBot(self.CurrentBot) # Saving bot

    def delete_cur_bot(self):
        os.remove('../Bots/' + self.CurrentBot.Name)
        self.CurrentBot = -1
        print('Removed')


    def loadBot(self, name = ''):
        startname = name

        if name == '':
            name = input('Enter bot name: ')

        BotFile = open('../Bots/' + name, 'rb+')

        bot = pickle.load(BotFile)

        self.CurrentBot = bot

        print(self.CurrentBot.Name)

        BotFile.close() # Closes file

        self.CurrentBot.Parent = self

        if startname == '':
            self.CurrentBot.botMenu(self)


    def saveBot(self, bot = 0):
        if bot == 0:
            bot = self.CurrentBot

        BotFile = open('../Bots/' + bot.Name, 'wb+') # Create or Open File

        BotFile.truncate() # Clear File
        pickle.dump(bot, BotFile, protocol=pickle.HIGHEST_PROTOCOL) # Write Bot Class

        BotFile.close() # Close file

    def editorMenu(self):
        actions = {
        'create': self.createBot,
        'load': self.loadBot,
        'save': self.saveBot,
        'exit': exit
        }

        while True:
            actions[input('Editor: ')]()

我可以创建bot并将其保存,并且所有变量都可以正确保存。我创建了Tkinter窗口,并且有指向我的Engine的链接。

from BotEngine.Editor import EditorClass
from BotEngine.GUI import App

if __name__ == '__main__':
   editor = EditorClass.Editor()

   root = App.tk.Tk()

   app = App.Main(root, editor)
   app.pack()

   root.title('Bot Engine')
   root.geometry("650x450+300+200")
   root.resizable(False, False)
   root.mainloop()

在我的TK窗口中,我有一个按钮-加载机器人。这是Button类。

class BotItem:
    def __init__(self, root, name):
        self.name = name
        self.root = root
        self.frame = ttk.Button(root.scroll, text=name, command=self.load_bot)
        self.frame.pack(side=tk.TOP, fill=tk.X)

    def load_bot(self):
        self.root.engine.loadBot(self.name)
        self.root.select_bot()

但是在第self.root.engine.loadBot(self.name)行上-Pickle举起AttributeError。最有趣的是,它仅适用于在控制台中创建的漫游器。仅在类EditorMenu中使用Editor函数。 使用GUI在App中创建的漫游器已正确加载。

这是错误:

AttributeError: Can't get attribute 'Editor' on
    <module '__main__' from '/Users/Name/Homework/BotEngine/Editor/Main.py'>

如果我要从Console App加载带有GUI的App中创建的漫游器,它将正确加载,但将停止在GUI App中加载。我该如何解决?

这是我用来在App中创建Bot的窗口:

class Child(tk.Toplevel):
    def __init__(self, root):
        super().__init__(root)
        self.root = root
        self.enter_name = -1
        self.btn_enter = -1
        self.init_child()

    def init_child(self):
        self.title('Create Bot')
        self.geometry('400x200+400+300')
        self.resizable(False, False)

        label_desc = tk.Label(self, text='Enter bot Name')
        label_desc.place(x=50, y=50)

        self.enter_name = ttk.Entry(self)
        self.enter_name.place(x=200, y=50)

        self.btn_enter = ttk.Button(self, text='Accept', command=self.create_bot)
        self.btn_enter.place(x=100, y=80)

        #self.grab_set()
        self.focus_set()

    def create_bot(self):
        self.root.engine.createBot(self.enter_name.get(), 'TOKEN')
        self.root.update_combobox()
        self.destroy()

root 是链接主窗口。 root.engine 是指向在程序启动(Editor)上创建的editor = EditorClass.Editor()的链接。

完整追溯

    Exception in Tkinter callback
    Traceback (most recent call last):
    File 
 "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 1702, in __call__
    return self.func(*args)
  File "/Users/Name/Homework/BotEngine/GUI/Icons/BotIcon.py", line 13, in load_bot
    self.root.engine.loadBot(self.name)
  File "/Users/Name/Homework/BotEngine/Editor/EditorClass.py", line 34, in loadBot
    bot = pickle.load(BotFile)
AttributeError: Can't get attribute 'Editor' on <module '__main__' from '/Users/Name/Homework/BotEngine/Editor/Main.py'>

1 个答案:

答案 0 :(得分:0)

无法运行的bot文件是通过运行其中包含Editor类的文件作为顶级脚本而创建的。执行此操作时,文件将以__main__模块的形式运行,而不是导入时的任何模块,并且它创建的Editor类是__main__.Editor而不是{{1 }}。 whatevernormalmodule.Editor的实例只能在__main__.Editor是存在的类的环境中才能被取消。

这是Python导入系统中非常不便的部分之一,也是尝试将文件同时用作模块和脚本的原因之一。最好的选择是重新创建您的bot文件。

相关问题