Python 函数是不可变的吗?

问题描述 投票:0回答:1

我有

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)

我可以设置

_member_b
的值,如下所示:

a = A()
a.set_b(some_actual_function_in_other_files) 

在另一个文件中,我有:

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)  # pass, because dictionary is mutable and deepcopy is not using the same reference
   self.assertIsNot(a._member_b, copy._member_b)  # fail, which means `a._member_b` and `copy._member_b` shares the same reference

我在copy.deepcopy()中理解,如果对象是不可变的,Python只使用复制引用(例如整数)。那么在这种情况下,

_member_b
是不可变的吗?

我相信是这样的,因为后来我更新了

copy._member_b
,我发现
a._member_b
仍然具有原始值,这意味着它不受副本更改的影响。是真的吗?

python python-3.x immutability deep-copy mutable
1个回答
0
投票

普通函数在 Python 中是可变的,但

copy.deepcopy
无论如何都不会复制它们:

此模块不复制模块、方法、堆栈跟踪、堆栈帧、文件、套接字、窗口或任何类似类型等类型。 它通过不变地返回原始对象来“复制”函数和类(浅层和深层);这与 pickle 模块处理这些的方式兼容。

import copy def func(): pass func2 = copy.deepcopy(func) func.is_mutable = True # no error print(func2.is_mutable) # True, not copied print(func is func2) # True, not copied
    
© www.soinside.com 2019 - 2024. All rights reserved.