检查函数是否在Julia中具有关键字参数

时间:2017-08-21 05:06:33

标签: julia metaprogramming

有没有办法检查函数是否在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

2 个答案:

答案 0 :(得分:2)

基本上,@ 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))
    ...

答案 1 :(得分:1)

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

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块中。