【问题标题】:Check if a function has keywords arguments in Julia检查函数在 Julia 中是否有关键字参数
【发布时间】:2018-01-29 02:04:04
【问题描述】:

有没有办法在 Julia 中检查函数是否有关键字参数?我正在寻找像 has_kwargs(fun::Function) 这样的东西,如果 fun 有一个带有关键字参数的方法,它将返回 true。

高层的想法是构建一个函数:

function master_fun(foo::Any, fun::Function, ar::Tuple, kw::Tuple)
    if has_kwargs(fun)
        fun(ar... ; kw...)    
    else 
        fun(ar...)
    end
end

【问题讨论】:

  • 为什么需要这样构建函数?我不知道foo 是什么,但是使用默认值怎么样:ar::Tuple=(), kw::Tuple=()?如果 fun 有 kwargs,大概 kw 持有它们(在你的例子中)。
  • 我有一个与此相关的问题:github.com/JuliaLang/julia/issues/20555
  • 感谢您的回答,如果您将 kw = () 传递给函数,则会引发 BoundsError。

标签: julia metaprogramming


【解决方案1】:

基本上,@Michael K. Borregaard 使用 try-catch 的建议是正确的并且正式有效。

查看非官方的实现细节,我想出了以下内容:

haskw(f,tup) = isdefined(typeof(f).name.mt,:kwsorter) &&
  length(methods(typeof(f).name.mt.kwsorter,(Vector{Any},typeof(f),tup...)))>0

这个函数首先查看泛型函数的任何方法上是否有任何关键字处理,如果有,则查看具体的类型元组。

例如:

julia> f(x::Int) = 1
f (generic function with 1 method)

julia> f(x::String ; y="value") = 2
f (generic function with 2 methods)

julia> haskw(f,(Int,))
false

julia> haskw(f,(String,))
true

这应该针对特定应用程序进行测试,因为当涉及非叶类型时它可能不起作用。正如迈克尔评论的那样,在问题的上下文中,声明将是:

if haskw(fun, typeof.(ar))
    ...

【讨论】:

  • 我忘记了:VERSION == v"0.7.0-DEV.1084"(Julia 0.6 及更高版本应该没问题)
  • 哇,你已经深入挖掘了 :-) 也许值得一提的是,在示例上下文中实现的方式是 haskw(fun, typeof.(ar))
【解决方案2】:

我认为您不能保证给定函数具有关键字参数。检查

f(;x = 3) = println(x)
f(x) = println(2x)
f(3)
   #6

f(x = 3)
   #3 

f(3, x = 3)
    #ERROR: MethodError: no method matching f(::Int64; x=3)
    #Closest candidates are:
    #  f(::Any) at REPL[2]:1 got unsupported keyword argument "x"
    #  f(; x) at REPL[1]:1

那么,f 函数有关键字吗?您只能检查给定的方法。请注意,在上面的示例中,您通常只需执行

function master_fun(foo, fun::Function, ar::Tuple, kw....)
    fun(ar... ; kw...)
end

这应该可以工作,如果关键字被传递给不接受它们的函数,您只需将错误报告留给fun。如果这不可接受,您可以尝试将 fun(ar...; kw...) 包装在 try-catch 块中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多