Python factory method with easy registry
1. Stop writing classes

The title for this section comes from Jack Diederich's PyCon 2012 talk.

A class represents a group of objects with similar behaviour, and an object represents some kind of persistent thing. So when deciding what classes a program is going to need, the first question to ask is, "what kind of persistent things does this program need to represent?"

In this case the program:


knows how to load NumPy arrays from different kinds of file format (CSV and plain text); and
knows how to compute the relative difference between two NumPy arrays (so long as they come from files with the same format).


The only persistent things here are files (represented by Python file objects) and NumPy arrays (represented by numpy.ndarray objects). So there's no need for any more classes.

2. Other review points


The code calls numpy.seterr to suppress the warning:

RuntimeWarning: invalid value encountered in true_divide


but it fails to restore the original error state, whatever it was. This might be an unpleasant surprise for the caller. It would be better to use the numpy.errstate context manager to ensure that the original error state is restored.
When dispatching to NumPy functions, it usually unncessary to check shapes for compatibility and raise your own error. Instead, just pass the arrays to NumPy. If they can't be combined, then NumPy will raise:

ValueError: operands could not be broadcast together ...



3. Revised code

Instead of classes, write a function!

import numpy as np

def relative_difference(t, r):
    """Return the relative difference between arrays t and r, that is:

    0              where t == 0 and r == 0
    (t - r) / r    otherwise

    """
    t, r = np.asarray(t), np.asarray(r)
    with np.errstate(divide='ignore', invalid='ignore'):
        return np.where((t == 0) &amp; (r == 0), 0, (t - r) / r)


Note the following advantages over the original code:


It's much shorter, and so there's much less code to maintain.
It can find the difference between arrays that come from files with different formats:

relative_difference(np.loadtxt(path1), np.fromfile(path2))

It can find the difference between arrays that don't come from files at all:

relative_difference(np.random.randint(0, 10, (10,)), np.arange(1, 11))