AttributeError: 'DataModuleClass' object has no attribute 'training_dataset'
I am trying to learn PyTorch Lightning by writing a very simple DataModuleClass. After prepare_data(), and setup() I am trying to check these functions are working or not. So, I am trying to get the training and validation dataset from setup(). But I am getting an error
AttributeError: 'DataModuleClass' object has no attribute 'training_dataset'

Code
def prepare_data(self):
    x = np.random.uniform(0, 10, 10)
    e = np.random.normal(0, self.sigma, len(x))
    
    # Making target or labels
    y = x + e
    
    # Marging x and e for 2 features
    X = np.transpose(np.array([x, e]))

    # Converting numpy array to Tensor
    self.x_train_tensor = torch.from_numpy(X).float().to(device)
    self.y_train_tensor = torch.from_numpy(y).float().to(device)
    
    training_dataset = TensorDataset(self.x_train_tensor, self.y_train_tensor)

    self.training_dataset = training_dataset

def setup(self):
    data = self.training_dataset
    self.train_data, self.val_data = random_split(data, [8, 2])
    return self.train_data, self.val_data
    
    
def train_dataloader(self):
    return DataLoader(self.train_data)

def val_dataloader(self):
    return DataLoader(self.val_data)
    
obj = DataModuleClass()
print(obj.setup())  

Could you tell me why I am getting this error?

From the way the code looks to me.
The variable self.training_dataset of the DataModuleClass is initiated in prepare_data and setup need it in the first line.
But you called setup without calling training_dataset.
If prepare_data is expected to be called every time you create a DataModuleClass object then it best to put prepare_data in __init__. Like
def __init__(self, other_params):
    ..... all your code previously in __init__
    self.prepare_data()  # put this in the last line of this function

But if you don't need that then you need to call prepare_data before setup
obj = DataModuleClass()
obj.prepare_data()
print(obj.setup())  

Or put prepare_data in setup itself.
def setup(self):
    self.prepare_data()
    data = self.training_dataset
    self.train_data, self.val_data = random_split(data, [8, 2])
    return self.train_data, self.val_data

Edit 1: See the actual value of self.train_data and self.val_data
The objects returned from setup are torch.utils.data.dataset.Subset.
There are basically 2 ways to get the tensors.
1. Treat them like lists
train_data, val_data = obj.setup()
print(train_data[0])

2. Use for loop
train_data, val_data = obj.setup()
for data in train_data:
    print(data)

Note
I'm not sure weather you'll get the tensors or TensorDataset. If it's the latter then use the same trick again, like
train_data, val_data = obj.setup()
train_tensor_data = train_data[0]
print(train_tensor_data[0])

