isinstance() 在列表中包含的对象上失败

问题描述 投票:0回答:1

这是预期的行为吗(如果是,有人可以解释为什么吗)? 这只发生在使用莳萝而不是泡菜时。

from pathlib import Path
import dill

class MyClass:

    def __init__(self) -> None:
        pass


path = Path('test/test.pkl')
# create parent directory if it does not exist
path.parent.mkdir(exist_ok=True)

x = [ MyClass() ]
dill.dump(x, path.open('wb'))
y = dill.load(path.open('rb'))
    
print(isinstance(x[0], MyClass)) # True
print(isinstance(y[0], MyClass)) # False ???

我在期待

True

python serialization deserialization pickle dill
1个回答
0
投票

原因是

dill
在反序列化对象时正在酸洗并重新创建
MyClass
类对象。因此,与反序列化的
MyClass
对象相比,
x[0].__class__
(也称为
y[0].__class__
)是不同的对象,这会导致
isinstance
检查针对
MyClass
失败。

相比之下,stdlib

pickle
模块将使用对该类的引用,这会导致您期望的行为,因为它会在反序列化对象时通过引用导入该类,而不是创建一个新类。

要使

dill
使用参考,请将
byref
设置设置为
True

byref=True
dill
的行为更像是通过引用腌制某些对象(如模块),而不是尝试腌制对象本身。

dill.settings['byref'] = True
x = [ MyClass() ]
dill.dump(x, path.open('wb'))
y = dill.load(path.open('rb'))
print(isinstance(x[0], MyClass)) # True
print(isinstance(y[0], MyClass)) # True

或者,您可以只使用 stdlib 中的

pickle
而不是
dill

pickle.dump(x, path.open('wb'))
y = pickle.load(path.open('rb'))
print(isinstance(x[0], MyClass)) # True
print(isinstance(y[0], MyClass)) # True
© www.soinside.com 2019 - 2024. All rights reserved.