python 可变和不可变变量
frc99 中本葱

今天读代码时,看到下面这行代码,很疑惑为什么total_controlnet_embedding会随着target而改变,之前写C++/Go的时候,变量赋值是开辟另一个内存空间,除非用指针才会指向同一个内存空间。

搜了下发现python中,当将一个可变对象(如列表、字典或张量)赋值给另一个变量时,这两个变量实际上指向同一个内存地址。因此,对其中一个变量的修改会影响到另一个变量,因为它们引用的是同一个对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for idx, item in enumerate(control):
target = None
if param.control_model_type.is_controlnet:
target = total_controlnet_embedding
if param.control_model_type == ControlModelType.T2I_Adapter:
target = total_t2i_adapter_embedding
if target is not None:
if batch_option_uint_separate:
for pi, ci in enumerate(outer.current_c_indices):
if pi % len(outer.control_params) != param_index:
item[ci] = 0
for pi, ci in enumerate(outer.current_uc_indices):
if pi % len(outer.control_params) != param_index:
item[ci] = 0
for pi, ci in enumerate(outer.current_uc_indices):
if pi % len(outer.control_params) != param_index:
item[ci] = 0
target[idx] = item + target[idx]
else:
target[idx] = item + target[idx]

发现自己真是学艺不精,一直以来以为python语法很简单,没有细看过规则,在次记录下其可变和不可变变量。

不可变对象

1、数字(整数,浮点数,复数)

譬如下面这个例子中的y就还是3,因为x引用了全新的变量6。

1
2
3
x = 3
y = x
x = x + 3

2、字符串

3、元组tuple

4、布尔值

5、“冻结”集(frozen-set)

1
x = frozenset([1, 2, 3])

可变对象

1、列表
当然需要注意一点的是,切片列表会创建对应列表子序列的新列表,下面有个例子可以说明。

1
2
3
4
x = [0, 1, 2, 3]
y = [:2] # y = [0, 1]
x[0] = -1 # 此时 x = [-1, 1, 2, 3]
y # 而 y = [0, 1]

2、词典dict

3、集set

4、NumPy数组

由 Hexo 驱动 & 主题 Keep