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)