【问题标题】:Julia: Is it possible to pass a dictionary of parameters to a function?Julia:是否可以将参数字典传递给函数?
【发布时间】:2021-07-29 08:34:17
【问题描述】:

我有一个要传递给函数的函数参数字典。例如:

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 中做类似的事情?

【问题讨论】:

  • params... 应该做你想做的事
  • 当我尝试得到一个错误时:MethodError: no method matching test_function(::Pair{String,Any}, ::Pair{String,Any})(我更新了我的帖子以添加错误。)

标签: types arguments julia metaprogramming keyword-argument


【解决方案1】:

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

但是,请注意,字典中的键(或对/元组的迭代器)必须是符号才能解包到关键字参数中:

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

有关详细信息,请参阅手册的 VarargsKeyword Arguments 部分。

【讨论】:

    【解决方案2】:

    编辑: 哎呀,卡梅伦的回答刚刚发布。我会把它留在这里以防万一,但老实说,它和他的回答几乎一样:-)

    在 Julia 中,通用函数签名是 f(args ; kwargs)。常规输入参数args 的名称并不重要,重要的是它们出现在函数签名中的顺序。相反,对于关键字参数kwargs,它的名称很重要,顺序并不重要。

    我们需要的最后一条信息是,对于argskwargs,喷溅运算符... 将容器的元素分离为函数签名的单个参数。

    所以,让我们将这一切应用到您的示例中。考虑以下两个函数:

    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,所以为了 splat 一个容器,我们只需使用一个向量或元组,例如:

    params = [1, "baz"]
    f1(params...)
    

    第二个函数只有kwargs,Julia 希望看到这些以Pair{Symbol,T} 的类型表示一些T<:Any。因此,如果我们构建字典以将关键字参数的名称(表示为 Symbol)映射到值,那么 splatting 运算符会将字典的每个条目都 splat 到函数签名中,如下所示:

    params = Dict(:foo=>1, :bar=>"baz")
    f2(; params...)
    

    请注意,我必须在函数调用中使用; 来表示没有args,只有kwargs

    当然,如果需要,您可以同时拥有两者,例如f3(vectorofargs... ; dictofargs...).

    【讨论】:

    • 一个问题有两个好的答案永远不会有坏处。您的答案包含我缺少的一些细节。 :) 虽然值得注意的是,您也可以将Tuple{Symbol, T} 插入关键字参数中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多