Yep! I understand.
If you change your code to be like this:
import torch
import torch.nn as nn

class Model(nn.Sequential):
  def __init__(self):
    super().__init__()
    [self.add_module("conv_{}".format(n), nn.Conv2d(3, 3, 1, 1, 0)) for n in range(2)]

m = Model()

print(m)
print(m.conv_0)

You will have a Sequential model that implicitly chains the output of conv_0 to the input of conv_1 so there is no need for the loop in the forward method.
If you want to get a layer, it will be available as a property that matches the string passed for the module name in add_module. So in this case m.conv_0 is how you would get at the first layer without looping and matching the name.
You can call it directly on some input like m.conv_0(torch.randn(1, 3, 4, 4)). Hope that helps!
If you want to keep something closer to what you have, you could also do:
from collections import OrderedDict as odict
import torch.nn as nn

class Model(nn.Module):
    def __init__(self):
        super().__init__()

        layers = odict(
            [
                ("conv_0", nn.Conv2d(3, 3, 1, 1, 0)),
                ("conv_1", nn.Conv2d(3, 3, 1, 1, 0))
            ]
        )

        self.net = nn.Sequential(layers)

    def forward(self, x):
        return self.net(x)

m = Model()

print(m.net.conv_0)

But it seems weird to use a Module to wrap a single Sequential container. Why not inherit from nn.Sequential directly?