<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def jkeys(jfile, key_path=None, in_memory=True, ignore_prefix=('.', '_')):
 """ get keys for initial json level, or at level after following key_path Parameters jfile : str, file_like or path_like if str, must be existing file or folder, if file_like, must have 'read' method if path_like, must have 'iterdir' method (see pathlib.Path) key_path : list[str] a list of keys to index into the json before returning keys in_memory : bool if true reads json into memory before finding keys (this is faster but uses more memory) ignore_prefix : list[str] ignore folders beginning with these prefixes Examples -------- ['a', 'b', 'c'] ['d', 'f'] ['dir1', 'dir2', 'dir3'] ['initial', 'meta', 'optimised', 'units'] """

    key_path = [] if key_path is None else key_path

    def eval_file(file_obj):
        if not in_memory:
            return _get_keys_ijson(file_obj, key_path)
        else:
            return _get_keys(file_obj, key_path)

    if isinstance(jfile, basestring):
        if not os.path.exists(jfile):
            raise IOError('jfile does not exist: {}'.format(jfile))
        if os.path.isdir(jfile):
            jpath = pathlib.Path(jfile)
            return _get_keys_folder(jpath, key_path, in_memory, ignore_prefix)
        else:
            with open(jfile, 'r') as file_obj:
                return eval_file(file_obj)
    elif hasattr(jfile, 'read'):
        return eval_file(jfile)
    elif hasattr(jfile, 'iterdir'):
        if jfile.is_file():
            with jfile.open('r') as file_obj:
                return eval_file(file_obj)
        else:
            return _get_keys_folder(jfile, key_path, in_memory, ignore_prefix)
    else:
        raise ValueError(
            'jfile should be a str, '
            'file_like or path_like object: {}'.format(jfile))