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

Python函数是否不可变?深拷贝函数引用问题咨询

关于Python深拷贝中函数对象的疑问

相关代码定义

类A的实现

import copy
class A:
   _member_a: dict[str, str]
   _member_b: Callable

   def set_b(self, func):
       self._member_b = func

   def deep_copy(self):
       return copy.deepcopy(self)

外部函数定义

def some_actual_function_in_other_files(self):
    # Implementation

def some_actual_function_in_other_files_2(self):
    # Implementation

测试代码

def test(self):
   a = A()
   a._member_a = {"test", "test"}
   
   a.set_b(some_actual_function_in_other_files)
   
   copy = a.deep_copy()
   self.assertIsNot(a._member_a, copy._member_a)  # 通过,因字典可变,深拷贝使用新引用
   self.assertIsNot(a._member_b, copy._member_b)  # 失败,说明两者引用相同

疑问与结论验证

  • 已知copy.deepcopy()对不可变对象会直接复制引用(如整数),此处的_member_b(函数对象)是否属于不可变对象?
  • 我认为它是不可变的,因为修改拷贝对象的_member_b后,原对象的_member_b仍保留原值,未受影响,这个结论是否正确?

解答

  1. 函数对象属于不可变对象:在Python中,函数对象本身是不可变的——你无法修改函数的核心属性(比如代码逻辑、名称、参数列表等),只能重新给变量赋值让它指向其他函数。正因为函数不可变,copy.deepcopy()会直接返回原引用,这就是测试中a._member_b和copy._member_b指向同一对象的原因。

  2. 你的结论是正确的,但逻辑要理清:修改拷贝对象的_member_b不影响原对象,本质是你修改的是拷贝对象的_member_b变量本身(让它指向新的函数),而非修改函数对象的内部内容。原对象的_member_b变量依然指向原来的函数,自然不会被影响。这一点也侧面印证了函数对象不可变——如果函数本身可变,修改拷贝的函数内容会同步影响原对象,但实际并不会发生这种情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:03:20