如何解决如何在运行时动态设置对象的方法当对象是 Gym 环境的实例时?
我想覆盖一个实例的方法。让我们将此实例/对象称为 env
。实例方法有一个签名为 f(self,other_parameter)
的方法,它实际上是不可公开访问的(不知道为什么,但你会在下面看到它没有列在类和对象的属性列表中:你能告诉我吗?我为什么?)。但是,根据 this answer,我得到了 new_f(other_parameter)
形式的函数,即没有 self
参数,我需要将其绑定到实例/对象。然而,这不是我的第一个问题。
我的第一个问题是,我从 this post 尝试过的任何方法似乎都不适用于我的情况,即新方法没有分配给对象:至少,这是我从事实中推断出来的该方法似乎没有被调用。您可以运行以下示例来查看问题。
import types
from pprint import pprint
import gym
class MyEnv(gym.Env):
def f(self,other_parameter):
print("other_parameter (original) =",other_parameter)
return 0
def step(self,action: int) -> tuple:
return [],self.f(action),False,{}
def reset(self):
return []
env_id = "my_env-v1"
env = MyEnv()
gym.envs.register(id=env_id,entry_point=lambda: env,max_episode_steps=200)
env = gym.make(env_id)
pprint(dir(env))
env.reset()
# CORRECTLY prints the following
# other_parameter (original) = 0
# ([],{})
print(env.step(0))
print("-" * 10)
def f(self,other_parameter):
print("other_parameter (new) =",other_parameter)
return 10
# IT DOES NOT SEEM TO TAKE ANY EFFECT.
# env.f = f
# EVEN IF I TRY OTHER METHODS,IT DOES NOT SEEM TO WORK.
env.f = types.MethodType(f,env)
# INCORRECTLY prints the following
# other_parameter (original) = 7
# ([],{})
# IT SHOULD PRINT
# other_parameter (new) = 7
# ([],10,{})
print(env.step(7))
我正在使用 gym 0.17.3
(只需执行 pip install gym==0.17.3
来安装它)。
出现此问题的原因可能是 Gym 环境是通过调用 gym.make(env_id)
创建的,这可能会执行一些魔术或奇怪的技巧。我已经查看了定义 make
的 this module,但我还不确定问题可能出在哪里。我真的需要在创建环境后设置其方法,因此如果您有关于如何操作的建议,我将不胜感激。
解决方法
我刚刚注意到,如果我尝试将新方法 f
绑定到 env
before 行 gym.envs.register(...)
,它可以工作,但我会想在注册后更改f
。
同时,我还注意到,gym 可以将您的环境对象包装到另一个类中。在上面的示例中,结果证明在 MyEnv
对象中创建了一个 TimeLimit
对象,这就是上面示例中的 env
变量所指向的内容。我还注意到 env
有另一个名为 env
的属性,它是类型为 MyEnv
的实际对象,因此我上面的示例仅通过更改行
env.f = types.MethodType(f,env)
到
env.env.f = types.MethodType(f,env)
这也解释了为什么before注册环境它有效,因为注册环境之前的env
实际上是MyEnv
的一个实例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。