您的当前位置:首页正文

浅拷贝copy(“=”)和深拷贝(“copy.deepcopy()”)

2024-11-29 来源:个人技术集锦

python中对于对象的拷贝分为浅拷贝(copy)和深拷贝(deepcopy)两种方式。

其中浅拷贝由“=”完成。而深拷贝由copy模块中deepcopy()函数担任。

我觉得深拷贝和浅拷贝的区别在于:
对于浅拷贝来说,如果有一方的内容发生了变化,另一方有可能也会发生变化
而深拷贝,无论哪一方发生什么样的变化,另一方都不会发生改变。

小例子:

深拷贝的一个例子(我们通过深拷贝创建了两个生成器“genA2B_ema”以及“genB2A_ema”):

        self.genA2B = ResnetGenerator(input_nc=3, output_nc=3, ngf=self.args.ch, n_blocks=self.args.n_res, img_size=self.args.img_size, args=self.args).to(self.args.device)
        self.genB2A = ResnetGenerator(input_nc=3, output_nc=3, ngf=self.args.ch, n_blocks=self.args.n_res, img_size=self.args.img_size, args=self.args).to(self.args.device)
        self.genA2B_ema = copy.deepcopy(self.genA2B).eval().requires_grad_(False)
        self.genB2A_ema = copy.deepcopy(self.genB2A).eval().requires_grad_(False)

最近遇到的一个错误(示例):

encoder_embedding = instantiation_model.encoder(encoder_smiles)
decoder_smiles_list = []
for i in range(args.mutation_times):
    # 变异多个位点
    mutated_embedding = muti_position_mutation_randomValue(encoder_embedding, args.mutataion_pos_num)

在对 encoder_embedding 进行变异,然后变异成 mutated_embedding 时,我的 encoder_embedding 总是会变化,我很奇怪是为什么?明明我没有修改encoder_embedding啊?

错就错在下面这个函数上了

def muti_position_mutation_randomValue(latent_embedding, mutation_position_num):
    latent_embedding_size = latent_embedding.size()
    # 随机选出 mutation_position_num 不重复的位置
    random_positions = random.sample(range(0, latent_embedding_size[1] - 1), mutation_position_num)
    for position in random_positions:
        latent_embedding[0][position] = random.uniform(-1, 1)

    return latent_embedding

muti_position_mutation_randomValue 函数直接修改了输入

  • 如果 muti_position_mutation_randomValue 函数直接修改了它的输入 latent_embedding,而这个输入又是一个对 encoder_embedding 的引用,那么对 latent_embedding 的任何更改都会反映在 encoder_embedding 上。
  • 在 Python 中,列表和其他复合数据类型是通过引用传递的。这意味着,如果你传递一个列表或数组到一个函数,并且这个函数修改了这个列表或数组,那么这些修改会影响原始的列表或数组。

为了解决这个问题,在 muti_position_mutation_randomValue 函数内部创建 latent_embedding 的一个副本,并对这个副本进行修改,而不是直接修改原始输入。这样可以保证原始的 encoder_embedding 不会被更改。以下是如何实现这一点的示例:

import copy

def muti_position_mutation_randomValue(latent_embedding, mutation_position_num):
    # 对latent_embedding进行深度复制
    mutated_embedding = copy.deepcopy(latent_embedding)

    # 其他代码保持不变
    latent_embedding_size = mutated_embedding.size()
    random_positions = random.sample(range(0, latent_embedding_size[1] - 1), mutation_position_num)
    for position in random_positions:
        mutated_embedding[0][position] = random.uniform(-1, 1)

    return mutated_embedding

具体的用法看以下链接:

显示全文