मैं स्प्लिट किए गए kwargs के क्षेत्र से कीवर्ड तर्क कैसे प्राप्त करूं?


9

अगर मेरे पास एक फ़ंक्शन हस्ताक्षर है f(args...; kwargs...), तो मैं एक विशिष्ट कीवर्ड कैसे प्राप्त कर सकता हूं kwargs? पूरी तरह से kwargs.xकाम नहीं करता है:

julia> f(args...; kwargs...) = kwargs.x
f (generic function with 1 method)

julia> f(x=1)
ERROR: type Pairs has no field x
Stacktrace:
 [1] getproperty(::Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:x,),Tuple{Int64}}}, ::Symbol) at ./Base.jl:20
 [2] #f#7(::Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:x,),Tuple{Int64}}}, ::typeof(f)) at ./REPL[2]:1
 [3] (::var"#kw##f")(::NamedTuple{(:x,),Tuple{Int64}}, ::typeof(f)) at ./none:0
 [4] top-level scope at REPL[3]:1

यह सवाल #helpdesk में जूलियालैंग स्लैक चैनल पर दिखाई दिया। बहुत उपयोगी जूलिया स्लैक के लिए एक स्वचालित आमंत्रण के लिए, बस https://slackinvite.julialang.org भरें

जवाबों:


10

ऐसा होने का कारण यह है कि चपटा कीवर्ड तर्क डिफ़ॉल्ट रूप से नामित टपल में संग्रहीत नहीं किए जाते हैं। हम देख सकते हैं कि वे कैसे संग्रहीत हैं:

julia> g(;kwargs...) = kwargs
g (generic function with 1 method)

julia> g(a=1)
pairs(::NamedTuple) with 1 entry:
  :a => 1

julia> g(a=1) |> typeof
Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:a,),Tuple{Int64}}}

इसलिए चपटा कवारों को बदले में किसी प्रकार की पुनरावृत्ति वस्तु के रूप में संग्रहित किया जाता है। हालाँकि, हम आसानी से उस kwargsइटामेटर को एक NamedTuple में बदल सकते हैं, जैसे: (;kwargs...)और फिर इसे उस तरीके से एक्सेस करें, जिसकी हम अपेक्षा करते हैं, इसलिए आपका उदाहरण इसमें अनुवाद करेगा।

julia> f(args...; kwargs...) = (;kwargs...).x
f (generic function with 1 method)

julia> f(x=1, y=2)
1

बेशक, ऐसा करने का अधिक मुहावरेदार तरीका इसके बजाय फ़ंक्शन लिखना होगा

julia> f(args...; x, kwargs...) = x
f (generic function with 1 method)

julia> f(x=1, y=2)
1

लेकिन यह मानता है कि आप उस नाम को जानते हैं जिसे आप xफ़ंक्शन लिखना चाहते हैं।


एक संक्षिप्त विचार: यदि हम अपने उदाहरण पर लौटते हैं g(;kwargs...) = kwargs, तो हम पुनरावृत्ति वस्तु के फ़ील्डनाम के लिए पूछ सकते हैं जैसे कि लौटाया नहीं गया था:

julia> g(x=1, y=2) |> typeof |> fieldnames
(:data, :itr)

हम्म, यह dataफील्ड क्या है ?

julia> g(x=1, y=2).data
(x = 1, y = 2)

अहा! इसलिए हम वास्तव में kwargs को एक नामित टपल के रूप में उपयोग कर सकते हैं, अर्थात f(;kwargs...) = kwargs.data.xकाम करेगा, लेकिन मैं इस दृष्टिकोण की सिफारिश नहीं करूंगा क्योंकि यह अनिर्दिष्ट व्यवहार पर निर्भर करता है, इसलिए यह एक मात्र कार्यान्वयन विवरण हो सकता है जो स्थिर होने की गारंटी नहीं है। जूलिया संस्करणों में।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.