Understanding polymorphism in Python I feel like I don't understand how polymorphism works in Python. Here is something I put together.

class _Tag(object):
    def __init__(self):
        #DisjointedTag and JoinedTag will bypass __init__.
        #Also, self will not be defined within this class.
        #Bottom line, this class is just for inheritance.
        raise NotImplementedError;

    def join_attributes(self):
        self.joined_pieces=''.join(self.funct_pieces);
        self.__class__=JoinedTag;

    def to_disjointed(self):
        self.__class__=DisjointedTag;

    def add_attribute(self, attribute, value):
        self.funct_pieces.insert(
            -1, ' {}="{}"'.format(attribute, value)
        );
        self.to_disjointed();

class Tag(_Tag):
    def __init__(self, name):
        self.funct_pieces=[
            i.format(name) for i in ['&lt;{0}', '&gt;{{}}&lt;/{0}&gt;']
        ];
        self.joined_pieces='';

    def __call__(self, contents):
        self.join_attributes();
        return self(contents);

class JoinedTag(_Tag):
    def __call__(self, contents):
        return self.joined_pieces.format(contents);

class DisjointedTag(_Tag):
    #JoinedTag.__call__ has 1 mandatory parameter so this also needs one.
    def __call__(self, place_holder):
        raise TypeError(
            '{} is disjointed because attributes were added to it.'.\
            format(self)
        );


Here is an example:

&gt;&gt;&gt; p=Tag('p')
&gt;&gt;&gt; p('hi')
'&lt;p&gt;hi&lt;/p&gt;'
&gt;&gt;&gt; p.add_attributes('align', 'left')
&gt;&gt;&gt; p.join_attributes();
&gt;&gt;&gt; p('hi')
'&lt;p align="left"&gt;hi&lt;/p&gt;'


I could have joined the attributes on every call but that would waste time. The code I made has no if statements, so it should be more readable according to the philosophy of polymorphism. However, it is very hard to read. I figure I've done something wrong or I'm not used to reading polymorphic code.
I'm a bear of very little brain, so I don't really understand what you are trying to achieve, or why you think polymorphism will help you achieve it.

But I did notice some problems with your code:


There's no documentation.
There are no test cases.
Python doesn't need semicolons at the end of lines.
You don't need a \ at the end of a line if the statement cannot end at that point because of an unclosed parenthesis.
There are no checks on the validity of entity and attribute names.
Values aren't escaped.
There's no check to stop the caller adding multiple attributes with the same name.
You shouldn't raise an exception class, you should raise an instance of that class (passing a suitable error message to the constructor).