Julia:是否可以将参数字典传递给函数?
Julia: Is it possible to pass a dictionary of parameters to a function?
我有一个要传递给函数的函数参数字典。例如:
function test_function(foo::Int, bar::String)
#...
end
params = Dict(
"foo" => 1,
"bar" => "baz"
)
在 Python 中,我可以像这样将所有参数作为 kwargs 传递:
def test_function(foo: int, bar: str):
#...
params = {
"foo": 1
"bar": "baz"
}
test_function(**params)
但是当我尝试 params...
时,出现以下错误:
julia> test_function(params...)
ERROR: MethodError: no method matching test_function(::Pair{String,Any}, ::Pair{String,Any})
有没有办法在 Julia 中做类似的事情?
Julia 明确区分了位置参数和关键字参数。为了阐明区别,您可以使用分号将位置参数与关键字参数分开。您可以使用 ...
将对象解包为位置参数或关键字参数,这被称为 splatting operator.
如果要将对象解包为关键字参数,它需要是对或元组的迭代器。如果将对象解包为位置参数,则解包的元素类型需要与函数的方法之一相匹配。
这是一个例子:
function foo(x, y; a=1, b=2)
x + y + a + b
end
t = (1, 2)
d = Dict(:a => 3, :b => 4)
julia> foo(t... ; d...)
10
但是,请注意字典中的键(或 pairs/tuples 的迭代器)必须是符号才能解包到关键字参数中:
julia> e = Dict("a" => 3, "b" => 4);
julia> foo(t... ; e...)
ERROR: MethodError: Cannot `convert` an object of type String
to an object of type Symbol
有关详细信息,请参阅手册的 Varargs and Keyword Arguments 部分。
编辑: 哎呀,就在卡梅伦回答之后发布了这个。我会把它留在这里以防它有帮助,但老实说,它说的和他的回答几乎一样:-)
在 Julia 中,泛型函数签名是 f(args ; kwargs)
。常规输入参数的名称 args
并不重要,重要的是它们在函数签名中出现的顺序。相反,对于关键字参数 kwargs
重要的是名称,顺序并不重要。
我们需要的最后一条信息是,对于 args
或 kwargs
,splatting 运算符 ...
将容器的元素分离为单独的参数,用于函数签名。
所以,让我们将这一切应用到您的示例中。考虑以下两个函数:
function f1(foo::Int, bar::String)::String
return "$(foo) --> $(bar)"
end
function f2( ; foo::Int=0, bar::String="nil")::String
return "$(foo) --> $(bar)"
end
第一个函数只有args
,第二个函数只有kwargs
。对于第一个函数,名称并不重要,因为我们正在处理 args
,因此为了展开一个容器,我们将使用向量或元组,例如:
params = [1, "baz"]
f1(params...)
第二个函数只有 kwargs
,Julia 希望看到这些表示为某些 T<:Any
的类型 Pair{Symbol,T}
。因此,如果我们构建字典以将关键字参数的名称(表示为 Symbol
)映射到值,则展开运算符会将字典的每个条目展开到函数签名中,如下所示:
params = Dict(:foo=>1, :bar=>"baz")
f2(; params...)
请注意,我必须在函数调用中使用 ;
来表示没有 args
,只有 kwargs
。
当然,如果需要,您可以同时拥有两者,例如f3(vectorofargs... ; dictofargs...)
.
我有一个要传递给函数的函数参数字典。例如:
function test_function(foo::Int, bar::String)
#...
end
params = Dict(
"foo" => 1,
"bar" => "baz"
)
在 Python 中,我可以像这样将所有参数作为 kwargs 传递:
def test_function(foo: int, bar: str):
#...
params = {
"foo": 1
"bar": "baz"
}
test_function(**params)
但是当我尝试 params...
时,出现以下错误:
julia> test_function(params...)
ERROR: MethodError: no method matching test_function(::Pair{String,Any}, ::Pair{String,Any})
有没有办法在 Julia 中做类似的事情?
Julia 明确区分了位置参数和关键字参数。为了阐明区别,您可以使用分号将位置参数与关键字参数分开。您可以使用 ...
将对象解包为位置参数或关键字参数,这被称为 splatting operator.
如果要将对象解包为关键字参数,它需要是对或元组的迭代器。如果将对象解包为位置参数,则解包的元素类型需要与函数的方法之一相匹配。
这是一个例子:
function foo(x, y; a=1, b=2)
x + y + a + b
end
t = (1, 2)
d = Dict(:a => 3, :b => 4)
julia> foo(t... ; d...)
10
但是,请注意字典中的键(或 pairs/tuples 的迭代器)必须是符号才能解包到关键字参数中:
julia> e = Dict("a" => 3, "b" => 4);
julia> foo(t... ; e...)
ERROR: MethodError: Cannot `convert` an object of type String
to an object of type Symbol
有关详细信息,请参阅手册的 Varargs and Keyword Arguments 部分。
编辑: 哎呀,就在卡梅伦回答之后发布了这个。我会把它留在这里以防它有帮助,但老实说,它说的和他的回答几乎一样:-)
在 Julia 中,泛型函数签名是 f(args ; kwargs)
。常规输入参数的名称 args
并不重要,重要的是它们在函数签名中出现的顺序。相反,对于关键字参数 kwargs
重要的是名称,顺序并不重要。
我们需要的最后一条信息是,对于 args
或 kwargs
,splatting 运算符 ...
将容器的元素分离为单独的参数,用于函数签名。
所以,让我们将这一切应用到您的示例中。考虑以下两个函数:
function f1(foo::Int, bar::String)::String
return "$(foo) --> $(bar)"
end
function f2( ; foo::Int=0, bar::String="nil")::String
return "$(foo) --> $(bar)"
end
第一个函数只有args
,第二个函数只有kwargs
。对于第一个函数,名称并不重要,因为我们正在处理 args
,因此为了展开一个容器,我们将使用向量或元组,例如:
params = [1, "baz"]
f1(params...)
第二个函数只有 kwargs
,Julia 希望看到这些表示为某些 T<:Any
的类型 Pair{Symbol,T}
。因此,如果我们构建字典以将关键字参数的名称(表示为 Symbol
)映射到值,则展开运算符会将字典的每个条目展开到函数签名中,如下所示:
params = Dict(:foo=>1, :bar=>"baz")
f2(; params...)
请注意,我必须在函数调用中使用 ;
来表示没有 args
,只有 kwargs
。
当然,如果需要,您可以同时拥有两者,例如f3(vectorofargs... ; dictofargs...)
.