def evaluate(ex, out=None, local_dict=None, global_dict=None, **kwargs):

    # First, get the signature for the arrays in expression
    context = getContext(kwargs)
    names, _ = getExprNames(ex, context)

    # Get the arguments based on the names.
    call_frame = sys._getframe(1)
    if local_dict is None:
        local_dict = call_frame.f_locals
    if global_dict is None:
        global_dict = call_frame.f_globals
    arguments = []
    types = []
    for name in names:
        try:
            a = local_dict[name]
        except KeyError:
            a = global_dict[name]
        arguments.append(a)
        if hasattr(a, 'atom'):
            types.append(a.atom)
        else:
            types.append(a)

    # Create a signature
    signature = [(name, getType(type_)) for (name, type_) in zip(names, types)]
    print("signature-->", signature)

    # Compile the expression
    compiled_ex = NumExpr(ex, signature, [], **kwargs)
    print("fullsig-->", compiled_ex.fullsig)

    _compute(out, compiled_ex, arguments)

    return
Refresh information used to show the changelist tree structure such as
dataset/ETHPy150Open PyTables/PyTables/bench/evaluate.py/evaluate--crossover with--dataset/ETHPy150Open feincms/feincms/feincms/admin/tree_editor.py/TreeEditor._refresh_changelist_caches