julia - 在字典形式的给定范围/上下文中进行评估的最佳方法?

标签 julia

我有一个字符串,例如z[2] 并且我想在上下文中eval它,例如字典(:z => 1:10)

最好的方法是什么?

我可以让它工作,但它非常慢。

function replace_expr(expr, d::Dict)
    return expr
end

function replace_expr(s::Symbol, d::Dict)
    get(d, s, s)
end

function replace_expr(expr::Expr, d::Dict)
    return Expr(replace_expr(expr.head, d),
                [replace_expr(e, d) for e in expr.args]...)
end


function eval_with(context::Dict{Symbol, Any}, expr_string::AbstractString)
    # E.g. :abc => :(s[:abc])
    d = Dict(k => :(s[$(Meta.quot(k))]) for k in keys(context))
    ex = parse("s -> $expr_string")
    ex = replace_expr(ex, d)
    return eval(ex)(context)
end

下面是测试

function make_context()
    x = 1
    y = "foo"
    z = 2:5

    Dict(
        :x => x,
        :y => y,
        :z => z
    )
end

const context = make_context()

@test eval_with(context, "x + 3") == 4
@test eval_with(context, "string(1, y, 1)") == "1foo1"
@test eval_with(context, "z[2]") == 3

@time eval_with(context, "z[2]")
# 0.004739 seconds (767 allocations: 40.728 KB)

最佳答案

这似乎是您可以更多地依赖 Julia 内置表达式求值机制的地方。 eval 采用可选参数:要在其中进行评估的模块。

您可以通过编程方式创建新模块:

julia> M = Module()
anonymous

您可以使用eval将字典中的值分配给该模块:

julia> context = Dict(
               :x => 1,
               :y => "foo",
               :z => 2:5
           );

julia> for (k,v) in context
           eval(M, :($k = $v))
       end

julia> M.x
1

julia> M.y
"foo"

现在,当然,您可以在模块的上下文中评估自定义字符串。

julia> eval(M, parse("x+3"))
4

julia> eval(M, parse("string(1, y, 1)"))
"1foo1"

像这样的动态评估不会是 Julia 的闪光点。我认为这将是最好的:

julia> @time eval(M, parse("z[2]"))
  0.000284 seconds (13 allocations: 672 bytes)
3

请注意,这与您上面编写的代码的语义略有不同;您的上下文中的变量仅在开始时填充......并且可能会因新的评估而更改。

还有usual caveats关于使用eval apply。通常还有其他更好的方法来构建程序,这些方法将提高性能、更易于理解且更易于维护。

关于julia - 在字典形式的给定范围/上下文中进行评估的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41639237/

相关文章:

julia - 在 Julia 中合并子图

garbage-collection - 内存不会在多个线程中释放

file-io - 从Julia的二进制文件中读取4字节字

input - 如何在 julia 的每次击键时读取键盘输入?

julia - 在 Julia 中读取未知大小的 BIN 文件?

performance - 复制!并在 Julia 中切片

julia - 在某点绘制与函数相切的线

julia - Julia中多个条件的三元运算符

julia - 如何编写一个函数来检查每个调用方法的返回类型是否可以静态推断?

plot - 在 Julia 中使用带有插值函数的 gr() 绘制等高线图