Workaround for Python 2.x hasattr() swallowing exceptions

Before Python3, hasattr(x, 'attr') would swallow exceptions, even
sh.ErrorReturnCode.  hasattr(sh.something, 'attr') can have side
effects, but this change tries to work around this to the extent it can,
by only causing side effects if the string object would actually have
the desired attribute.

I ran into this behavior in code that was trying to decide whether
something was a file, so it did hasattr(something, 'read').  It seemed
reasonable, but it caused the entire output of the command to be read
into memory, and any exceptions to be swallowed.