检查 Julia 中是否存在关键字参数。

5

我有一个函数使用...来收集额外的关键字参数,就像这样function f(args=0; kwargs...)。我想检查一个关键字参数,比如说a,是否存在于kwargs中。

我的做法可能不太优雅,我首先创建一个Dict来存储关键字和相应的值kwargs_dict=[key=>value for (key, value) in kwargs],然后我使用haskey(kwargs_dict, :a)来检查a是否是字典中的一个键。然后我通过kwargs_dict[:a]来获取它的值。

function f(; kwargs...)
   kwargs_dict = [key=>value for (key, value) in kwargs]
   haskey(kwargs_dict, :a)
   a_value = kwargs_dict[:a]
end

f(args=0, a=2)
> true

f(args=0)
> false

我想知道是否有更好的方法来检查关键字参数a是否在kwargs中,并获取已存在关键字参数的值。
4个回答

7
您可以通过将 `kwargs` 传递给 `Dict` 构造��数来获得 `kwargs` 的字典表示。例如:
kwargs_dict = Dict(kwargs)

谢谢,这是一种优雅的创建字典的方式。 - Conta

4

另一种方法是为命名关键字变量使用默认值。默认值是一个特殊值(也称为sentinel value)。当用户提供一个值时,它会覆盖默认值,这很容易检查。 nothing 是一个常用的值。具体来说,对于问题中的示例:

julia> function g(; a = nothing, kwargs...)
    kwargs_dict = [key=>value for (key, value) in kwargs]
    a != nothing
end
g (generic function with 1 method)

提供以下功能:
julia> g(args=0, a=2)
true
julia> g(args=0)
false

优势之一是第一速度-默认值的关键字参数可以避免使用kwargs字典,如果可能的话,优化会放弃整个字典设置代码。第二个优势可能是可读性(但各有所好)。

1
在许多情况下这是一个好方法,但一定要注意类型不稳定性:` #= 好 =# f(;a::Int=0) = a; g(use::Bool) = use ? f(a=1) : f(); @code_warntype g(true);#= 坏 =# f(;a=nothing) = a==nothing ? 0 : a; g(use::Bool) = use ? f(a=1) : f(); @code_warntype g(true) ` - Zach

1
我的建议是:您也可以定义
function f(; kwargs...)
    keys = [k for (k, v) ∈ kwargs]
    :a ∈ keys
end

如果您只想在未提供 kwarg 的情况下提供一个值,也可以执行以下操作:

function f(; kwargs...)
    a = get(kwargs, :a, "my default value for a")
end

这使您能够

julia> f(ab = "a")
"my default value for a"

julia> f(a = "a")
"a"

1

我认为最直接且无需分配内存的方法(至少从Julia 1.6开始)是检查

:a in keys(kwargs)

如果为真,您可以使用以下方法检索值:

a = values(kwargs).a

这是一个稍微改动过的示例:

function f(; kwargs...)
    if :a in keys(kwargs)
        a = values(kwargs).a
        if a > 0
            return true
        end
    end
    return false
end

julia> @btime f(a=2)
  0.900 ns (0 allocations: 0 bytes)
true

julia> @btime f(b=2)
  0.900 ns (0 allocations: 0 bytes)
false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接