use callable() instead of hasattr(x, '__call__')