unittest无法从泡菜导入类(AttributeError:无法获取属性...) [英] unittest unable to import class from pickle (AttributeError: Can't get attribute...)

查看:34
本文介绍了unittest无法从泡菜导入类(AttributeError:无法获取属性...)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要单元测试以将以前保存的类加载到泡菜中.但是,当我在单元测试中加载泡菜时(出于单元测试的目的),它会引发错误:

I need a unittest to load a previously saved class in a pickle. However, when I load the pickle in the unittest (out of unittest works), it raises the error:

AttributeError:无法在< module上获取属性'Foo'"... \ unittest \ 主要 .py">

保存类的代码示例(我将此代码保存在 run_and_save_class.py 中):

Code example to save the class (I save this code in run_and_save_class.py):

from pickle import dump
from pickle import load
from pickle import HIGHEST_PROTOCOL

class Foo(object):
    
    def __init__(self):
        self.bar = None
        self.file_out = "./out.pkl"

    def save_class(self):
        with open(self.file_out, "wb") as file_out:
            dump(self, file_out, protocol=HIGHEST_PROTOCOL)
            
    def load_class(self):
        with open(self.file_out, "rb") as file_out:
            cls = load(file_out)
        return cls

if __name__ == "__main__":
    cls = Foo()
    cls.bar = "saving a bar"
    cls.save_class()

测试类的代码(我将此代码保存在 unittest_class.py 中):

Code to test the class (I save this code in unittest_class.py):

import unittest
from run_and_save_class import Foo


class ClassValidation(unittest.TestCase):
    
    def __init__(self, *args, **kwargs):
        print("init")
        self.cls = Foo
        self.instance = Foo().load_class()
        print("class loaded")
        unittest.TestCase.__init__(self, *args, **kwargs)
    
    def test_anything(self):
        pass

我在Anaconda Prompt中运行:

I run in Anaconda Prompt:

python run_and_save_class.py

python -m unittest -v unittest_class.py

后者是引发错误的那个.

The latter is the one that raises the error.

但是,这可以在笔记本电脑上工作.

However, this works in a notebook.

from run_and_save_class import Foo
cls = Foo().load_class()

我不明白为什么它不在单元测试中.

I don't understand why it doesn't in a unittest.

推荐答案

问题是,泡菜相对于 __ main __ 保存了对象,在其中 dump 被调用(通过 save_class ).要加载相同的对象,您必须提供相同的环境-解决方法是在测试中将类添加到 __ main __ 中,以便pickle可以找到它:

The problem is that pickle saves the object relative to __main__, where dump was called (via save_class). To load the same object, you have to provide the same environment - a workaround is to add the class to __main__ in your test, so that pickle can find it:

import __main__

class ClassValidation(unittest.TestCase):

    def __init__(self, *args, **kwargs):
        __main__.Foo = Foo
        self.cls = Foo
        self.instance = Foo().load_class()
        unittest.TestCase.__init__(self, *args, **kwargs)

    def test_anything(self):
        self.assertEqual("saving a bar", self.instance.bar)

这篇关于unittest无法从泡菜导入类(AttributeError:无法获取属性...)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆