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

Python的copy.deepcopy无法正确复制Gym环境LunarLanderContinuous-v2的问题求解

Python的copy.deepcopy无法正确复制Gym环境LunarLanderContinuous-v2的问题求解

我之前也碰到过类似的Gym环境复制问题,确实用标准库的copy.deepcopy处理这类环境时容易踩坑——很多Gym环境的类并没有正确实现__deepcopy__方法来处理所有自定义属性,就像你遇到的这样,复制后的环境居然自动切换成了离散版本的配置,属实让人头大。

先还原一下你遇到的问题场景,代码如下:

import gym, copy
env = gym.make('LunarLanderContinuous-v2')
print(env.action_space) 
print(env.continuous)
env1 = copy.deepcopy(env)
# env1.continuous = True
print(env1.action_space)
print(env1.continuous)

运行后输出:

action_space Box(-1.0, 1.0, (2,), float32)
continuous True
action_space Discrete(4)
continuous False

问题原因分析

出现这个问题的核心原因是,LunarLanderContinuous-v2本质是基于基础的LunarLander环境修改了continuous参数,但copy.deepcopy在复制时没有正确保留这些参数配置,反而重置回了默认的离散版本属性。Gym的很多环境类内部的属性初始化逻辑并没有考虑deepcopy的场景,导致复制过程中关键的配置属性(比如continuous)没有被正确拷贝,进而触发了环境属性的错误重置。

可行的解决办法

这里有几个实用的解决思路,你可以根据自己的使用场景选择:

  • 手动同步关键配置属性:这是最直接的临时解决方案,在deepcopy之后,手动把原环境的关键属性赋值给复制后的环境,就像你代码里注释掉的那行其实就有效果,扩展一下:

    env1 = copy.deepcopy(env)
    # 手动同步核心配置属性
    env1.continuous = env.continuous
    env1.action_space = env.action_space
    # 如果有其他必要的配置属性,比如observation_space也可以同步
    

    这样就能让复制后的环境和原环境保持一致的配置了。

  • 重新创建环境并同步状态:如果担心deepcopy带来的其他潜在问题,也可以直接重新创建一个相同配置的环境,然后把原环境的运行状态同步过去(如果需要保留当前环境的运行进度的话):

    env1 = gym.make('LunarLanderContinuous-v2')
    # 同步原环境的运行状态(如果原环境已经执行过步骤)
    env1.state = env.state
    env1.steps_beyond_done = env.steps_beyond_done
    # 其他需要同步的状态属性可以根据实际运行需求添加
    

    这种方式更稳妥,因为直接用正确的配置初始化环境,从根源上避免了deepcopy的未知问题。

  • 自定义环境类的__deepcopy__方法:如果需要频繁复制这个环境,可以给LunarLander的环境类添加自定义的__deepcopy__方法,确保所有关键属性都被正确复制。不过这种方式需要修改环境类的代码,适合有一定源码修改经验的场景:

    from gym.envs.box2d.lunar_lander import LunarLander
    
    def custom_deepcopy(self, memo):
        # 用当前环境的配置创建新实例
        new_env = LunarLander(continuous=self.continuous)
        # 同步运行状态
        new_env.state = self.state.copy()
        new_env.steps_beyond_done = self.steps_beyond_done
        # 可以根据需要添加其他需要复制的属性
        memo[id(self)] = new_env
        return new_env
    
    # 替换原类的__deepcopy__方法
    LunarLander.__deepcopy__ = custom_deepcopy
    

    这样之后再用copy.deepcopy复制环境时,就会按照我们定义的逻辑来处理,不会再出现配置错误的情况了。

备注:内容来源于stack exchange,提问作者PerceptualRobotics

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:54:34