定义OpenAI Gym Env子类step方法时提示缺失必填位置参数如何解决?
问题原因
- 重写Gym的
Env父类方法时错误使用了@Env.step、@Env.render、@Env.reset装饰器。父类的对应方法是实例方法,直接以类名调用方法作为装饰器会破坏方法的实例绑定逻辑,调用时系统无法自动注入self参数,原本的step(self, action)方法会被识别为需要传入两个位置参数,调用时仅传入action的情况下就会提示缺少参数。 - 若测试代码中调用
step方法时没有传入动作参数,也会触发该报错。
解决方案
- 移除三个重写方法上的错误装饰器,Gym自定义环境不需要额外加这类装饰器,直接重写父类方法即可,修改后的类代码如下:
from gym import Env from gym.spaces import Discrete, Box import numpy as np import random class ShowerEnv(Env): def __init__(self): # 可执行动作:降温、保持温度、升温 self.action_space = Discrete(3) # 温度观测范围 self.observation_space = Box(low=np.array([0]), high=np.array([100])) # 设置初始温度 self.state = 38 + random.randint(-3,3) # 设置淋浴总时长 self.shower_length = 60 def step(self, action): # 执行动作调整温度 # 0对应-1℃,1对应0℃,2对应+1℃ self.state += action -1 # 淋浴剩余时长减1秒 self.shower_length -= 1 # 计算奖励 if self.state >=37 and self.state <=39: reward =1 else: reward = -1 # 判断当前episode是否结束 if self.shower_length <= 0: done = True else: done = False info = {} # 返回观测、奖励、结束标识、额外信息 return self.state, reward, done, info def render(self): # 可自行实现可视化逻辑 pass def reset(self): # 重置初始温度 self.state = 38 + random.randint(-3,3) # 重置淋浴时长 self.shower_length = 60 return self.state
- 调用
step方法时必须传入合法的动作参数,可直接从动作空间采样随机动作,正确的调用示例如下:
from ShowerEnv import ShowerEnv import time env = ShowerEnv() while True: # 采样随机动作 action = env.action_space.sample() # 调用step方法传入动作 obs, reward, done, info = env.step(action) print(f"当前温度:{obs}, 执行动作:{action}, 奖励:{reward}") # episode结束后重置环境 if done: env.reset() print("===== 重置环境 =====") time.sleep(1)
内容的提问来源于stack exchange,提问作者Veer Bhandaru
相关产品推荐
相关产品推荐

