Julia 有没有类似于 Python 的 literal_eval
函数?Python 中这个函数由包 ast
(Abstract Syntax Tree) 提供。
literal_eval
是用来评估 Python 字面结构的函数,包括字符串、字节、数字、元组、列表、字典、集合、布尔值和 None
。当需要安全地对来自不可信源的字符串进行计算时,可以使用该函数,无需手动解析这些值。但该函数不能评估任意复杂的表达式,例如包含运算符或索引等表达式。
Julia 有没有类似于 Python 的 literal_eval
函数?Python 中这个函数由包 ast
(Abstract Syntax Tree) 提供。
literal_eval
是用来评估 Python 字面结构的函数,包括字符串、字节、数字、元组、列表、字典、集合、布尔值和 None
。当需要安全地对来自不可信源的字符串进行计算时,可以使用该函数,无需手动解析这些值。但该函数不能评估任意复杂的表达式,例如包含运算符或索引等表达式。
julia> :([1,2,3]) |> dump
Expr
head: Symbol vect
args: Array{Any}((3,))
1: Int64 1
2: Int64 2
3: Int64 3
typ: Any
julia> f() = [1,2,3]
f (generic function with 2 methods)
julia> @code_lowered f()
CodeInfo(:(begin
nothing
return (Base.vect)(1, 2, 3)
end))
julia> methods(Base.vect)
# 3 methods for generic function "vect":
vect() in Base at array.jl:63
vect(X::T...) where T in Base at array.jl:64
vect(X...) in Base at array.jl:67
因此,[1,2,3]
只是一个语法形式,它被转换为对Base.vect
函数的调用,即Base.vect(1,2,3)
。现在,我们可能会在未来使一些函数“封闭”,以便不能添加任何子方法或以任何方式重写其行为,但目前可以完全修改Base.vect
对某些参数集的行为:
julia> function Base.vect(a::Int, b::Int, c::Int)
warn("SURPRISE!")
return invoke(Base.vect, Tuple{Any,Any,Any}, a, b, c)
end
julia> [1,2,3]
WARNING: SURPRISE!
3-element Array{Int64,1}:
1
2
3
julia> Dict(:foo => 1, :bar => 2, :baz => 42)
Dict{Symbol,Int64} with 3 entries:
:baz => 42
:bar => 2
:foo => 1
Dict
类型进行函数调用,使用了三个键值对作为参数,根本不是字面量语法。而 a => b
的形式本身也只是对 =>
操作符进行函数调用的特殊语法,它是 Pair
类型的别名。julia> dump(:(a => b))
Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol =>
2: Symbol a
3: Symbol b
typ: Any
julia> :foo => 1.23
:foo=>1.23
julia> =>
Pair
julia> Pair(:foo, 1.23)
:foo=>1.23
Int
值,没有任何可重载的入口点(但是这可能会在将来改变,允许用户代码选择不同的整数字面量行为)。然而,足够大的整数字面量会被降级为宏调用,例如:julia> :(18446744073709551616)
:(@int128_str "18446744073709551616")
Int64
类型的范围,则会将其降级为一个宏调用,并使用包含整数数字的字符串参数,使得宏能够解析该字符串并返回一个适当的整数对象——在这种情况下是一个Int128
值,以便将其拼接到抽象语法树中。但您可以为这些宏定义新的行为:julia> macro int128_str(s)
warn("BIG SUPRISE!")
9999999999999999
end
julia> 18446744073709551616
WARNING: BIG SUPRISE!
9999999999999999
Meta.parse
可以完成这项工作: 最初的回答
julia> eval(Meta.parse("[1,2,3]"))
3-element Array{Int64,1}:
1
2
3
Meta.parse
将您的字符串转换为Expr
,然后eval
将其转换为可用的数据结构。在Julia 1.0中绝对有效。
原始答案: "最初的回答"
https://discourse.julialang.org/t/how-to-convert-a-string-into-an-expression/11160