Library to verify GTINs of various lengths
I assume the variety of GTIN's are a bounded set.  If so, I see no use
in the inheritance.  Go with Option #2. And on that option I would recommend a
few changes

Pre-build your formats into a dict based on length:

This pre-builds and compiles the format regex's

formats = {l: re.compile(r'^[0-9]{{{}}}[0-9?]{{1}}$'.format(l - 1))
           for l in (8, 12, 13, 14)}


Add a __str__ method for easier debugging:

This makes it easier to see what is going on in the debugger.

def __str__(self):
    return self.gtin if self.gtin is not None else 'invalid'


If you have an early return, put it in the if, not else:

I would generally code something like this:

if len(gtin) in cls.ALLOWED_LENGTHS:
    self.length = len(gtin)
else:
    return False


as this:

if len(gtin) not in cls.formats:
    return False
....


Define a __len__ method if needed:

I removed the self.length as it was not used internally, and a better way to publish the length is with a __len__.

def __len__(self):
    return len(self.gtin) if self.gtin is not None else 0


Consume bool evaluations directly:

If you need a bool and are performing a test to determine the bool state, you rarely need an if.  I redid this:

if re.match(format, gtin):
    return True
return False


as this (with some other changes also incorporated):

return cls.formats[len(gtin)].match(gtin) is not None


So there is no reason for the if, the result of the test can be returned (or assigned to a variable) directly.

Entire Class:

import re

class GTIN:
    formats = {l: re.compile(r'^[0-9]{{{}}}[0-9?]{{1}}$'.format(l - 1))
               for l in (8, 12, 13, 14)}

    def __init__(self, gtin):
        self.gtin = self.parse(gtin)

    def __str__(self):
        return self.gtin if self.gtin is not None else 'invalid'

    def __len__(self):
        return len(self.gtin) if self.gtin is not None else 0

    @classmethod
    def parse(cls, gtin):
        parsed_gtin = cls.sanitize(gtin)
        if not cls.check_format(parsed_gtin):
            return None
        return parsed_gtin

    @classmethod
    def sanitize(cls, gtin):
        return re.sub(r'[\s\-]+', '', gtin)

    @classmethod
    def check_format(cls, gtin):
        if len(gtin) not in cls.formats:
            return False
        return cls.formats[len(gtin)].match(gtin) is not None