code: def instancelist(obj_list, check=False, shared_attrs=None):
      class InstanceList_(object):
          def __init__(self, obj_list, shared_attrs=None):
              self._obj_list = []
              self._shared_public_attrs = []
              self._example_type = None
              if len(obj_list) > 0:
                  import utool as ut
                  self._obj_list = obj_list
                  example_obj = obj_list[0]
                  example_type = type(example_obj)
                  self._example_type = example_type
                  if shared_attrs is None:
                      if check:
                          attrsgen = [set(dir(obj)) for obj in obj_list]
                          shared_attrs = list(reduce(set.intersection, attrsgen))
                      else:
                          shared_attrs = dir(example_obj)
                  allowed = []
                  self._shared_public_attrs = [
                      a for a in shared_attrs
                      if a in allowed or not a.startswith('_')
                  ]
                  for attrname in self._shared_public_attrs:
                      attrtype = getattr(example_type, attrname, None)
                      if attrtype is not None and isinstance(attrtype, property):
                          setattr(InstanceList_, attrname,
                                  property(self._define_prop(attrname)))
                      else:
                          func = self._define_func(attrname)
                          ut.inject_func_as_method(self, func, attrname)
          def __nice__(self):
              if self._example_type is None:
                  typename = 'object'
              else:
                  typename = self._example_type.__name__
              return 'of %d %s(s)' % (len(self._obj_list), typename)
          def __repr__(self):
              classname = self.__class__.__name__
              devnice = self.__nice__()
              return '<%s(%s) at %s>' % (classname, devnice, hex(id(self)))
          def __str__(self):
              classname = self.__class__.__name__
              devnice = self.__nice__()
              return '<%s(%s)>' % (classname, devnice)
          def __getitem__(self, key):
              return self._map_method('__getitem__', key)
          def _define_func(self, attrname):
              import utool as ut
              def _wrapper(self, *args, **kwargs):
                  return self._map_method(attrname, *args, **kwargs)
              ut.set_funcname(_wrapper, attrname)
              return _wrapper
          def _map_method(self, attrname, *args, **kwargs):
              mapped_vals = [getattr(obj, attrname)(*args, **kwargs)
                             for obj in self._obj_list]
              return mapped_vals
          def _define_prop(self, attrname):
              import utool as ut
              def _getter(self):
                  return self._map_property(attrname)
              ut.set_funcname(_getter, 'get_' + attrname)
              return _getter
          def _map_property(self, attrname):
              mapped_vals = [getattr(obj, attrname) for obj in self._obj_list]
              return mapped_vals
      return InstanceList_(obj_list, shared_attrs)