考虑以下功能:
function func(vars::Dict{Symbol, Any})
end
我想在func
的范围内创建局部变量,
哪里:
变量名都是vars
和vars
的关键
变量值是与给定键对应的eval()
中的值。
我知道我可以使用for (k, v) in vars
eval(:($k = $v))
end
之类的内容:
JuMP
但是,这将定义全局范围内的变量,这会产生性能影响并可能覆盖现有的全局变量。
P.S。如果您的建议与我要采用的方法截然不同,我会添加一个上下文。我正在围绕JuMP实现一个包装器,允许用户使用任意约束表达式动态创建优化模型。由于约束表达式是使用符号定义的,并且import pandas as pd
data = pd.read_csv(filename)
data2 = df[['A','B','C']] #put 'A' 'B' 'C' in the desired order
data2.to_csv(filename)
要求在当前作用域中定义这些符号,因此我希望用户将这些符号及其值在字典中提供给函数。全局定义符号将是麻烦的,因为用户理想情况下应能够使用相同的约束表达式(即相同的符号)但不同的值多次运行该函数。
答案 0 :(得分:1)
注意:我不是元编程专家!
我认为你可以做这样的事情,不是使用泛型函数,而是使用宏或生成函数。
基于此:
julia> macro bar(dict)
dump(dict, 10)
end
julia> @bar Dict(:foo => "foo", :bar => "bar", :baz => "baz");
Expr
head: Symbol call
args: Array(Any,(4,))
1: Symbol Dict
2: Expr
head: Symbol =>
args: Array(Any,(2,))
1: Expr
head: Symbol quote
args: Array(Any,(1,))
1: Symbol foo
typ: Any
2: ASCIIString "foo"
typ: Any
3: Expr
head: Symbol =>
args: Array(Any,(2,))
1: Expr
head: Symbol quote
args: Array(Any,(1,))
1: Symbol bar
typ: Any
2: ASCIIString "bar"
typ: Any
4: Expr
head: Symbol =>
args: Array(Any,(2,))
1: Expr
head: Symbol quote
args: Array(Any,(1,))
1: Symbol baz
typ: Any
2: ASCIIString "baz"
typ: Any
typ: Any
我能够做这样的事情,它可以做更多的错误检查,并且通用宏会使开发分支中的这更容易(至少用于错误检查):
julia> macro foo(dict)
blk = Expr(:block)
if dict.head == :call && dict.args[1] == :Dict
for arg in dict.args[2:end]
sym = arg.args[1].args[1]
val = arg.args[2]
push!(blk.args, esc(:($sym = $val)))
end
else
error("Need a Dict{Symbol, Any}")
end
blk
end
julia> @foo Dict(:foo => "foo", :bar => "bar", :baz => "baz");
julia> @show foo bar baz;
foo = "foo"
bar = "bar"
baz = "baz"
julia> let # local scope
@foo Dict(:foo => "foo", :bar => "bar", :baz => "baz")
@show foo bar baz
end;
foo = "foo"
bar = "bar"
baz = "baz"
请注意,您无法创建dict变量,然后将其传递给@foo
宏(再次generic macros可以使这更容易,因为Symbol
也可以使用方法和派遣错误?):
julia> dict = Dict(:foo => "foo", :bar => "bar", :baz => "baz");
julia> @foo dict
ERROR: type Symbol has no field head
此时的内容如下:
@foo a 1 b 2 c 3
或
@foo :a=>1 :b=>2 :c=>3
恕我直言会更好。
如果有人解释我为什么这不是最佳的,我会非常感激!这个答案应该是一个评论,但它是很多代码。
我将尝试使用通用宏和生成的函数实现类似的功能并更新帖子。