2017-08-21 64 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))' –