Pickle поднимает AttributeError при загрузке - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть 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: ')]()

Я могу создать бота, сохранить его, и все переменные сохранятся правильно.Я создал окно 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) - Пикл поднимает AttributeError.Самое интересное, что это происходит только для ботов, созданных в консоли.Только с использованием функции EditorMenu в классе Editor.Боты, созданные в приложении с графическим интерфейсом, загружаются правильно.

Это ошибка:

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

Если я загружу бот, созданный в приложении, с графическим интерфейсом из консольного приложения, он загрузится правильно, но будетпрекратить загрузку в приложении с графическим интерфейсом.Как это исправить?

Это окно, которое я использую для создания бота в приложении:

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 голосов
/ 28 ноября 2018

Файлы ботов, которые вы не можете загрузить, были созданы путем запуска файла с классом Editor в качестве сценария верхнего уровня.Когда вы делаете это, файл запускается как модуль __main__ вместо того модуля, который был бы, если бы вы его импортировали, и класс Editor, который он создает, равен __main__.Editor вместо whatevernormalmodule.Editor.Экземпляры __main__.Editor могут быть не выбраны только в среде, где __main__.Editor - это класс, который существует.

Это одна из очень неудобных частей системы импорта Python, и одна из причин, по которой пытаются использоватьФайл как модуль и скрипт не очень хорошо работает.Лучше всего, вероятно, восстановить файл бота.

...