首页 > 解决方案 > Python - 将烧瓶应用程序的名称更改为 app.py 时出现 ModuleNotFoundError。可能的解决方案?

问题描述

我最近将我的主要烧瓶应用程序文件从 inputServer.py 更改为 app.py 以增加易用性。

我抛出错误的代码如下:

def readBackupPlayers(objectFile):
    with open(objectFile, 'rb') as openedFile:
        manager.playerList = pickle.load(openedFile)
    print('Backup of players retrieved')

^ 读取自定义pickle文件的函数,该文件用于备份存储在自定义对象中的列表

class PlayerManager:
    def __init__(self):
        self.playerList = []
        self.ID = len(self.playerList) + 1
        self.currentGame = None
        self.tournament = None


manager = PlayerManager()

^ 声明类并创建它的实例以用于在整个程序中存储变量的代码。

错误信息:

File "c:\users\simon\appdata\local\programs\python\python38-32\lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\simon\OneDrive\Documents\AtomTesting\app.py", line 356, in setup
    readBackupPlayers('Backups/playerBackup')
  File "C:\Users\simon\OneDrive\Documents\AtomTesting\app.py", line 72, in readBackupPlayers
    manager.playerList = pickle.load(openedFile)
ModuleNotFoundError: No module named 'inputServer'

目录:

AtomTesting -
   Backups -
      playerBackup
      tournamentBackup
   Static -
      static Flask files (not relevant)
   templates -
      Flask templates (not relevant)
   app.py (renamed from inputServer.py)
   config.py
   README.md

标签: pythonflask

解决方案


这是正在发生的事情。Python 的 pickle 模块根据名称对 Python 对象进行序列化和反序列化(转储和加载)。由于您的班级所在的模块的名称发生了变化,Pickle 无法弄清楚如何重新实例化这些对象。

但是,Python wiki 上有详细说明的解决方案。它涉及将旧名称映射到新名称:

import pickle


renametable = {
    'inputServer': 'app',
    }

def mapname(name):
    if name in renametable:
        return renametable[name]
    return name

def mapped_load_global(self):
    module = mapname(self.readline()[:-1])
    name = mapname(self.readline()[:-1])
    klass = self.find_class(module, name)
    self.append(klass)

def loads(str):
    file = StringIO(str)
    unpickler = pickle.Unpickler(file)
    unpickler.dispatch[pickle.GLOBAL] = mapped_load_global
    return unpickler.load()

或者,这可能是一种更好的方法,您不应该将 pickle 用于任何严重的数据存储,尤其是当您的应用程序版本之间可能使用某些东西时。

您可能会考虑将 ORM 与轻量级数据库(如 SQLite)一起使用。


推荐阅读