def __init__(self, data=None, columns=None, index=None): self._data = [] self._columns = [] self._index = [] # Use public setters to validate data if columns is not None: self.columns = list(columns) if index is not None: self.index = list(index) if not data: self._init_empty() elif isinstance(data, Table): self._init_table(data) elif is_dict_like(data): self._init_dict(data) elif is_list_like(data): self._init_list(data) else: raise TypeError("Not a valid input format") if columns: self._sort_columns(columns) self._validate_self()
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
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 test_is_dict_like(obj, result): assert types.is_dict_like(obj) == result