class_docstr: Encapsulates an existing nn.Module to make it subclass MultiTaskModule,
  the user should still be able to interact with the encapsulated module
  as if it was the module itself.
  
  The only things that change are the following, the classifier from the
  given model will be replaced by a MultiHeadClassifier, and the forward()
  implementation will be overwritten by one that accepts task labels.
  The encapsulated module will then be automatically extended to
  fit new classes during calls to model.adaptation()
code: def __getattr__(self, name):
      # Override pytorch impl from nn.Module
  
      # Its a bit particular since pytorch nn.Module does not
      # keep some attributes in a classical manner in self.__dict__
      # rather it puts them into _parameters, _buffers and
      # _modules attributes. We have to add these lines to avoid recursion
      if name == "model":
          return self.__dict__["_modules"]["model"]
      if name == self.classifier_name:
          return self.__dict__["_modules"][self.classifier_name]
  
      # If its a different attribute, return the one from the model
      return getattr(self.model, name)
  
file_path: avalanche/avalanche/models/helper_method.py
imports: import torch
  import torch.nn
  from avalanche.models.dynamic_modules import MultiTaskModule, MultiHeadClassifier
label_desc: Use image node_id 4 for calling the MultiTaskDecorator obj's underlying member method code with example usage: obj.__getattr__(name) and returns: getattr, self, self