2017-08-21 42 views
1

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

高水平的想法是建立一个功能:

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

为什么你需要用这种方式构建函数?我不知道'foo'是什么,但是如何使用默认值:'ar :: Tuple =(),kw :: Tuple =()'?如果有趣的是kwargs,那么kw可能会持有它们(在你的例子中)。 –

+0

我有一个问题打开与此有关:https://github.com/JuliaLang/julia/issues/20555 –

+0

感谢您的回答,如果您将它传递给函数,使用kw =()会引发BoundsError。 – Maxime

回答

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

2

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

展望非官方的实现细节,我想出了followng:

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 

这应该针对特定应用进行测试,因为它可能在非叶类涉及不起作用。正如Michael所评论的那样,在问题的背景下,声明将是:

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

我忘记了:'VERSION == v“0.7.0-DEV.1084”'(Julia 0.6 and up should be ok) –

+1

哇,你挖得很深:-)也许值得一提的是,这样做的方式在这个例子的上下文中就是'haskw(fun,typeof。(ar))' –

相关问题