Improve __getattr__ for VecEnvWrapper
See original GitHub issueIn more complicated experiments, a user may wish to wrap a VecEnv with multiple instances of VecEnvWrapper
in a modular fashion. For example, we could have something like below:
class RewardVecWrapper(VecEnvWrapper):
def __init__(self, venv, reward_multiplier):
super().__init__(venv)
self._reward_multiplier = reward_multiplier
def step_wait(self):
obs, rewards, dones, infos = self.venv.step_wait()
rewards *= self._reward_multiplier
return obs, rewards, dones, infos
def get_reward_multiplier(self):
return self._reward_multiplier
class LoggingVecWrapper(VecEnvWrapper):
def custom_log(self, infos):
# stateful logging, saving to file in custom format, etc.
...
def step_wait(self):
obs, rewards, dones, infos = self.venv.step_wait()
self.custom_log(infos)
return obs, rewards, dones, infos
The issue arises if I have a venv which has been wrapped with RewardVecWrapper
and and I wish to call get_reward_multiplier
. Depending on if I have wrapped it with LoggingVecWrapper
(or any number of wrappers really), I would have to do some unappealing type-checking, something to the effect of
def get_arbitrarily_deep_reward_multiplier(wrapped_venv):
reward_venv = wrapped_venv
while True:
if isinstance(reward_venv, RewardVecWrapper):
return reward_venv.get_reward_multiplier()
else:
reward_venv = reward_venv.venv
I believe we can fix this by modifying VecEnvWrapper.__getattr__
to the following:
# in class VecEnvWrapper
def __getattr__(self, name):
# Edit: line below was originally "return self.venv.__getattr__(name)"
return getattr(self.venv, name)
This way, as long as different VecEnvWrappers have unique names for attributes of interest, one can always find that attribute from a top-level call to venv.__getattr__
.
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (1 by maintainers)
Top Results From Across the Web
Vectorized Environments - Stable Baselines - Read the Docs
Wraps a VecEnv or VecEnvWrapper object to record rendered image as mp4 video. It requires ffmpeg or avconv to be installed on the...
Read more >Crash when extending VecEnvWrapper · Issue #844 - GitHub
Bug When you try to extend the VecEnvWrapper, and put a breakpoint in the construction function of the new class, pycharm crashes due...
Read more >Stable Baselines Documentation - Read the Docs
Stable Baselines is a set of improved implementations of Reinforcement ... reference is being hidden in a recursive call to __getattr__.
Read more >TeachMyAgent.students.openai_baselines.common.vec_env ...
class VecEnvWrapper (venv, observation_space=None, action_space=None). An environment wrapper that applies to an entire batch of environments at once.
Read more >Python: using getattr for properties and methods
Before we jump into how getattr can be a useful tool for DRYing up our code, lets cover how it works (docs here)!...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
__getattr__
is called when the attribute is not found for that object. This is in contrast to__getattribute__
, which is called every time an attribute reference is made.A warning wouldn’t actually break code, but I appreciate the concern.