这是预期的行为吗(如果是的话,有人可以解释为什么)? 这只会发生在使用Dill,而不是pickle.

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块.

推荐答案

这是因为dill在对你的对象进行重命名时,正在pickle和重新创建MyClass类对象.因此,MyClass(也是x[0].__class__)是一个不同的对象,而y[0].__class__对象则导致isinstance判断对MyClass失败.

print(id(MyClass))
# 140430969773264

print(id(x[0].__class__)) # same as above
# 140430969773264

print(id(y[0].__class__)) # different
# 140430969780544

相比之下,stdlib pickle模块将使用对类的引用,这导致了您所期望的行为,因为它将通过引用导入类,而不是创建一个新类.

要创建dill个使用引用,请将byref设置设置为True

byref=Truedill的行为更像pickle,通过引用pickle某些对象(如模块),而不是试图pickle对象本身.

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

Python相关问答推荐

Python Hashicorp Vault库hvac创建新的秘密版本,但从先前版本中删除了密钥

2维数组9x9,不使用numpy.数组(MutableSequence的子类)

Odoo 14 hr. emergency.public内的二进制字段

Pystata:从Python并行运行stata实例

ModuleNotFound错误:没有名为Crypto Windows 11、Python 3.11.6的模块

如何根据参数推断对象的返回类型?

导入...从...混乱

如果满足某些条件,则用另一个数据帧列中的值填充空数据帧或数组

如何从列表框中 Select 而不出错?

不允许 Select 北极滚动?

如果有2个或3个,则从pandas列中删除空格

使用polars. pivot()旋转一个框架(类似于R中的pivot_longer)

Python—在嵌套列表中添加相同索引的元素,然后计算平均值

如何在PythonPandas 中对同一个浮动列进行逐行划分?

为什么dict. items()可以快速查找?

每次查询的流通股数量

Polars表达式无法访问中间列创建表达式

删除另一个div中的特定div容器

按最大属性值Django对对象进行排序

将鼠标悬停在海运`pairplot`的批注/高亮显示上