python - pickle 如何创建一个实例来无视构造函数?

标签 python pickle

我的最终目标是拥有一个具有常规构造函数的类,还有一个可用于创建该类的部分实例化版本的第二个构造函数。

class Foo(object):
   def __init__(self, foo, bar):
      self.foo = foo
      self.bar = bar
   def create_partial(self, **kwargs):
      self.foo = kwargs.get('foo', None)
      self.bar = kwargs.get('bar', None)

我注意到 pickle 以某种方式实现了这一点。您可以编写仅处理其中一个参数的 __getstate____setstate__ 函数,它会忽略您尚未定义其中一个参数的事实。例如

class Foo(object):
  def__init__(self, foo, bar):
    self.foo = foo
    self.bar = bar
  def __getstate__(self):
    return {'foo': self.foo}
  def __setstate__(self, d):
    self.foo = d['foo']

然后我可以 pickle 和 unpickle 一个实例来得到一个半实例化的对象

myfoo = pickle.loads(pickle.dumps(Foo(1,2)))
print(myfoo.foo) # 1
print(myfoo.bar) # throws AttributeError
type(myfoo) # __main__.Foo

所以,我的问题是,它如何设法获取该类的一个空白实例,将其实例化一半并让它仍然将其类型报告为 Foo,此外,我如何在不必通过 pickle 的情况下执行相同的操作?

附言我知道这是一件想要做的疯狂事情,但我想知道怎么做

最佳答案

当您运行 Foo() 时,我们将其视为调用 Foo.__init__()。但实际上,在此之前还有一个额外的步骤,即创建对象。 foo = Foo(a, b, c) 大致等同于

foo = Foo.__new__(Foo, a, b, c)
foo.__init__(a, b, c)

__new__是一种很少使用的魔术方法,它实际上构造 对象。您几乎不需要重写它(重写它的最常见用例是在对 float 等内置类型进行子类化时),并且大多数类都继承了默认的 object.__new__。我们可以直接调用后一个函数。

# Assuming that Foo doesn't override __new__
myfoo = Foo.__new__(Foo)
# Or, to be extra safe
myfoo = object.__new__(Foo)

请注意 __new__ 将预期的类型作为第一个参数,因此即使我们调用 object.__new__,我们仍然会得到一个 Foo因为我们传递了 Foo 作为参数。在此过程中没有施 worker 员受到伤害。

关于python - pickle 如何创建一个实例来无视构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68766253/

相关文章:

python - 我可以在单元测试中比较 2 个 float 的相似性但不相等吗?

python - 如何使用 Python Flask 获取复选框 "on"而不会导致 400 错误请求错误?

python - 运行时错误 : PytorchStreamReader failed locating file data. pkl:找不到文件

python - pickle 和 tkinter 的问题

Python2 : Should I use Pickle or cPickle?

python - 将 django manage.py 输出(在 Windows 中)重定向到文本文件

python - 基于无组织表创建字典的SQL语句

python - 默认调用父构造函数?

python - 如何在不下载的情况下从Azure Blob读取pickle文件?

python - 拆酸危害