DataParallel does have a self.module variable:

  
      github.com
  
  
    pytorch/pytorch/blob/df8d6eeb19423848b20cd727bc4a728337b73829/torch/nn/parallel/data_parallel.py#L131

        self.module = module
        self.device_ids = []
        return


    if device_ids is None:
        device_ids = list(range(torch.cuda.device_count()))
    if output_device is None:
        output_device = device_ids[0]


    self.dim = dim
    self.module = module
    self.device_ids = list(map(lambda x: _get_device_index(x, True), device_ids))
    self.output_device = _get_device_index(output_device, True)
    self.src_device_obj = torch.device("cuda:{}".format(self.device_ids[0]))


    _check_balance(self.device_ids)


    if len(self.device_ids) == 1:
        self.module.cuda(device_ids[0])


def forward(self, *inputs, **kwargs):



  
  
    
    
  
  


The following code works for me:
import torch.nn as nn
import torch
from torch.nn.parallel import DataParallel

class DataParallelWrapper(DataParallel):
    def __init__(self, module):
        super().__init__(module)


    def __getattr__(self, name):
        try:
            return super().__getattr__(name)
        except AttributeError:
            return getattr(self.module, name)


dpw = DataParallelWrapper(nn.Linear(2, 2))
print(getattr(dpw, "forward"))
print(getattr(dpw, "weight"))