Some tweaks:<p>#1:<p><pre><code> elif not isinstance(fn_transform, FunctionType) or not isinstance(fn_transform, LambdaType):
raise TypeError('Transformation parameter should be a function or lambda i.e. fn = lambda x: x.replace(a,b)')
</code></pre>
What about using callable()? There's no reason you couldn't use a functor, for example.<p>#2:<p><pre><code> curr = file_handle.read(chunk_size)
if encoding:
curr = curr.decode(encoding)
</code></pre>
That assumes a single-byte encoding. Consider a multi-byte encoding where the chunk_size reads only part of the character:<p><pre><code> >>> s="ü"
>>> s.encode("utf8")[:1].decode("utf8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 0: unexpected end of data
</code></pre>
#3:<p><pre><code> if chr(terminator) in chunk:
lines = chunk.split(chr(terminator))
</code></pre>
Might want to compute chr(terminator) once, rather than re-evaluate it each time.<p>#4:<p><pre><code> try:
transformations = iter(fn_transform)
yield list(map(lambda x: reduce(lambda a,b: b(a), fn_transform, x), columns))
except TypeError:
yield list(map(fn_transform, columns))
</code></pre>
Since you've already checked for the two cases, set a flag to remember what fn_transform contains. Then branch on that, rather than use the try/except.<p>Otherwise, consider what happens if one of the callables raises a TypeError because of an internal error, rather than because of an expected structural mismatch.