python - Python 中使用 __getattr__ 方法对对象进行 Pickle 返回 `TypeError, object not callable`

标签 python python-3.x pickle

我想定义一个类,使用 __getattr__ 方法为未知属性返回 None

完成此操作后,我尝试将该类的对象转储到 Pickle。

但是,我收到了错误

Traceback (most recent call last):
  File "c:\SVN\Scripts\Rally\examples\t_pickle_None.py", line 14, in <module>
    pickle.dump(toto, f, pickle.HIGHEST_PROTOCOL)
TypeError: 'NoneType' object is not callable

如果不定义__getattr__,它工作正常,但我想保留这个功能。

这是我的代码:如何使其与 __getattr__ 一起工作?

谢谢

import pickle
from typing import Any

class Toto:
    def __init__(self, name:str) -> None:
        self.name = name

    def __getattr__(self, _: str) -> Any:
        """Return None for all unknown attributes"""
        return None

toto = Toto("Toto")
with open('toto.pkl', 'wb') as f:
    pickle.dump(toto, f, pickle.HIGHEST_PROTOCOL)

最佳答案

问题是pickle尝试检查你的对象是否有__getstate__方法,可用于自定义对象的 pickle 方式。由于您的类没有定义 __getstate__ 方法,因此您的 __getattr__ 方法最终会被调用并返回 None。 Pickle 尝试调用此 None 值,这会产生您得到的异常。

有两种方法可以解决此问题:

  1. 在类中定义 __getstate__ 和相应的 __setstate__ 方法:

    def __getstate__(self):
        return vars(self)
    
    def __setstate__(self, state):
        vars(self).update(state)
    
  2. 重写您的 __getattr__ 方法以更好地处理 dunder-attributes(即抛出 AttributeError 而不是返回无意义的值):

    def __getattr__(self, attr: str) -> Any:
        """Return None for all unknown attributes"""
        if attr.startswith('__') and attr.endswith('__'):
            raise AttributeError
        return None
    

关于python - Python 中使用 __getattr__ 方法对对象进行 Pickle 返回 `TypeError, object not callable`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50888391/

相关文章:

python - 当使用 tensorflow 和我自己的数据时如何决定批量大小?

python - python 中的 for 循环需要可迭代对象或迭代器对象。因此以下两个 for 循环产生相同的结果

Python:更改导入文件类型的优先级(.py 在 .so 之前)

Python - 在用户加入时发送消息

python - 有没有办法 pickle FTP 对象?

python - 使用 Popen.wait() 时重现死锁

python - 构建 python 扩展时如何指定链接器?

python - Spyder 快捷方式的目标文件是什么?

python - 如何将 python 字典 pickle 到 MySQL 中?

python - 在类里面调用时出现 pickle 错误