Which class structure is better for what purposes. This one:

class Text:

    def __init__(self, passage):
        self.s = passage

    def read_text(self):
        return self.s

    def grow(self, sentence):
        self.s = self.s + sentence.s

class Sentence(Text):

    def __init__(self, sentence):
        Text.__init__(self, sentence)
        self.s = sentence

    def format(self):
        self.s = self.s[:1].title() + self.s[1:len(self.s)-1] + ".  "

class Word(Sentence):

    def __init__(self, word):
        Sentence.__init__(self, word)
        self.s = word

    def is_word(word, dict):
        return word.s in dict

    def add_space(self):
        self.s = self.s + " "

class Char(Word):

    def __init__(self, char):
        Word.__init__(self, char)
        self.s = char

or this one:

class Text:

    def __init__(self, text):
        self.t = text

    def __str__(self):
        return self.t

    def is_char(self):
        return len(self.t) == 1 and self.t in string.ascii_lowercase

    def is_word(self):
        return chr(32) not in self.t and chr(44) not in self.t and chr(46) not in self.t

    def is_sentence(self):
        return self.t[0] in string.ascii_uppercase and self.t[len(self.t)-1] == "."

    def not_last_word(self):
        return self.t + " "

    def grow(self, input):
            return self.t + input.t
            return self.t + input

You are wrapping the str class. It means that you want a string, but you don't want the string methods (such as addition or index(), etc). Instead, you want your own methods.

Did you consider subclassing str like this

class Sentence(str):
    __slots__ = ()

    def __new__(cls, *args):
        s = ''.join(str(a) for a in args)
        return str.__new__(cls, s)

    def is_char(self):
        return len(self) == 1 and 97 <= ord(self) < 123

    # etc

You can add more methods, and you have more friendly instances, which can use the usual str methods.

That sounds like an excellent idea. Thanks!