2017-08-21 1 views
1

Gibt es eine Möglichkeit zu überprüfen, ob eine Funktion Schlüsselwörter in Julia hat? Ich suche nach etwas wie has_kwargs(fun::Function), das true zurückgeben würde, wenn Spaß eine Methode mit Schlüsselwortargumenten hat.Überprüfen Sie, ob eine Funktion Schlüsselwörter in Julia hat.

Die hohe Idee ist, eine Funktion zu bauen:

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

Warum müssen Sie eine Funktion auf diese Weise erstellen? Ich weiß nicht, was 'foo' ist, aber was ist mit den Standardwerten:' ar :: Tuple =(), kw :: Tuple =() '? Wenn Spaß Kwargs hat, hält vermutlich Kw sie (in Ihrem Beispiel). –

+0

Ich habe ein Problem offen in Bezug auf diese: https://github.com/JuliaLang/julia/issues/20555 –

+0

Danke für Ihre Antwort, mit kw =() löst einen BoundsError, wenn Sie es an eine Funktion übergeben. – Maxime

Antwort

1

Ich glaube nicht, können Sie garantieren, dass eine bestimmte Funktion Schlüsselwort Argumente hat. Überprüfen Sie

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 

Also, hat die Funktion f Schlüsselwörter? Sie können nur nach einer bestimmten Methode suchen. Beachten Sie, dass oben in Ihrem Beispiel, würden Sie normalerweise nur

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

, die funktionieren sollte, und ob die Suchbegriffe an eine Funktion übergeben werden, die sie nicht nehmen Sie würden nur den Fehler lassen fun berichten. Wenn das nicht akzeptabel ist, könnten Sie versuchen, die fun(ar...; kw...) in einen try-catch-Block zu wickeln.

2

Grundsätzlich ist @ Michael K. Borregaards Vorschlag, try-catch zu verwenden, korrekt und funktioniert offiziell.

Blick in die inoffiziellen Implementierungsdetails, kam ich mit dem followng up:

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

Diese Funktion sucht zuerst, ob es eine Keyword-Verarbeitung auf einem beliebiges Verfahren der gattungsgemäßen Funktion ist, und wenn ja, schaut auf dem bestimmtes Tupel von Typen.

Zum Beispiel:

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 

Dies sollte für die spezielle Anwendung getestet werden, da es wahrscheinlich nicht funktioniert, wenn Nicht-Blatt-Typen beteiligt sind. Wie Michael bemerkte, würde im Zusammenhang mit der Frage die folgende Aussage lauten:

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

Und ich vergaß: 'VERSION == v" 0.7.0-DEV.1084 "' (Julia 0.6 und höher sollte in Ordnung sein) –

+1

Wow, du hast tief gegraben :-) Vielleicht erwähnenswert, dass die Art und Weise dies implementiert werden würde im Zusammenhang mit dem Beispiel wäre 'haskw (Spaß, Typof. (ar))' –

Verwandte Themen