def _column_value_getter(self, obj): """Create callable that returns column values for given object types.""" if is_namedtuple(obj): # Get values using properties def get(obj, column): return getattr(obj, column, None) elif is_dict_like(obj): # Get values using dictionary keys def get(obj, column): return obj.get(column) elif is_list_like(obj): # Get values using list indexes def get(obj, column): col = self.column_location(column) try: return obj[col] except IndexError: return None else: # Fallback to single column def get(obj, _): return obj return get
def _column_name_getter(self, obj): """Create callable that returns column names for given obj types.""" if is_namedtuple(obj): # Use namedtuple fields as columns def get(obj): return list(obj._fields) elif is_dict_like(obj): # Use dictionary keys as columns def get(obj): return list(obj.keys()) elif is_list_like(obj): # Use either predefined columns, or # generate range-based column values predefined = list(self._columns) def get(obj): count = len(obj) if predefined: if count > len(predefined): raise ValueError( f"Data had more than defined {count} columns") return predefined[:count] else: return list(range(count)) else: # Fallback to single column def get(_): return self._columns[:1] if self._columns else [0] return get