You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用multiprocessing的spawn启动方式时,__getattr__中调用self.a引发无限循环的原因咨询

Why does __getattr__ enter an infinite loop when using multiprocessing with spawn start method?

Let's break down exactly what's happening here, step by step:

1. Core difference between spawn and fork

  • When using fork (Unix default), the child process clones the parent's entire memory space. Your TestObject instance—including its self.a lambda—is copied directly, no serialization required. That’s why the code works when you remove set_start_method("spawn").
  • When using spawn, the child starts a fresh Python interpreter. The parent must serialize objects (via pickle) to pass them to the child, and the child deserializes them to reconstruct the objects.

2. Lambda functions can’t be pickled

Your TestObject’s self.a is a lambda: self.a = lambda *args: {}. Standard pickle can’t serialize lambda functions—they lack a stable name or source reference needed to reconstruct them in the child process.

When the parent tries to pickle testobject, it fails to save self.a, so this attribute is lost in the serialized data. When the child deserializes the object, the resulting TestObject instance has no a attribute at all.

3. The infinite loop trigger

When the child runs print(self.testobject), Python tries to generate a string representation of the object. The default __repr__ (used when no custom string methods are defined) will attempt to access instance attributes, or some internal mechanism will trigger a lookup for a missing attribute. Here’s the critical loop:

  • The child’s TestObject has no a attribute (lost during pickling).
  • Any attempt to access a missing attribute (like during the print call’s formatting) invokes __getattr__.
  • Your __getattr__ returns self.a—but self.a doesn’t exist, so accessing it triggers __getattr__ again.
  • This creates an infinite cycle: __getattr__ → try to get self.a → __getattr__ → try to get self.a → repeat forever.

Quick fixes to resolve this

You have a few straightforward options:

  • Replace the lambda with a named function (named functions are picklable):
    def a_func(*args):
        return {}
    
    class TestObject:
        def __init__(self) -> None:
            self.a = a_func
        def __getattr__(self, item):
            return self.a
    
  • Implement __getstate__ and __setstate__ methods in TestObject to handle serialization manually, ensuring self.a is properly reconstructed in the child.
  • Avoid passing objects with unpicklable attributes to spawned processes entirely.

内容的提问来源于stack exchange,提问作者Xiaobu Yang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:27:40