** kwargs का उद्देश्य और उपयोग क्या है?


763

**kwargsपाइथन के लिए क्या उपयोग हैं ?

मुझे पता है कि आप objects.filterएक टेबल पर कर सकते हैं और एक **kwargsतर्क में पास हो सकते हैं ।  

क्या मैं समय की देरी को निर्दिष्ट करने के लिए भी ऐसा कर सकता हूं timedelta(hours = time1)?

वह कितना सटीक काम करता है? क्या यह 'अनपैकिंग' की तरह है? पसंद है a,b=1,2?


27
यदि आप इस प्रश्न पर मुझसे टकराते
राशिद

3
यहाँ एक उल्लेखनीय संक्षिप्त विवरण है : "* एक टपल में सभी स्थिति संबंधी तर्क एकत्र करता है", "** एक शब्दकोश में सभी कीवर्ड तर्क एकत्र करता है"। कुंजी शब्द एकत्रित है
osa

24
जस्ट एफवाईआई: का kwargsअर्थ है KeyWord ARGumentS, तर्क है कि चाबियाँ निर्धारित की गई हैं
रिचर्ड डी विट

जवाबों:


868

आप **kwargsअपने कार्यों को मनमाने ढंग से कीवर्ड तर्क देने के लिए उपयोग कर सकते हैं ("kwargs" का अर्थ है "कीवर्ड तर्क"):

>>> def print_keyword_args(**kwargs):
...     # kwargs is a dict of the keyword args passed to the function
...     for key, value in kwargs.iteritems():
...         print "%s = %s" % (key, value)
... 
>>> print_keyword_args(first_name="John", last_name="Doe")
first_name = John
last_name = Doe

**kwargsकीवर्ड तर्कों के शब्दकोश का निर्माण करके और इसे अपने फ़ंक्शन में पास करके फ़ंक्शन को कॉल करते समय आप सिंटैक्स का उपयोग कर सकते हैं :

>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'}
>>> print_keyword_args(**kwargs)
first_name = Bobby
last_name = Smith

अजगर ट्यूटोरियल यह कैसे काम करता है, कुछ अच्छा उदाहरण के साथ का एक अच्छा विवरण शामिल हैं।

<- अद्यतन ->

पुनरावृत्तियों () के बजाय, पायथन 3 का उपयोग करने वाले लोगों के लिए, आइटम का उपयोग करें ()


1
@ yashas123 नहीं; यदि आप किसी ऐसी चीज़ पर लूप करते हैं जो खाली है, तो कुछ भी नहीं होता है, इसलिए जो भी कोड हो सकता है वह सामान्य रूप से अगला रन हो।
JG

330

शब्दकोशों को खोलना

** शब्दकोश शब्दकोशों।

इस

func(a=1, b=2, c=3)

के समान है

args = {'a': 1, 'b': 2, 'c':3}
func(**args)

यदि आपको मापदंडों का निर्माण करना है तो यह उपयोगी है:

args = {'name': person.name}
if hasattr(person, "address"):
    args["address"] = person.address
func(**args)  # either expanded to func(name=person.name) or
              #                    func(name=person.name, address=person.address)

एक फ़ंक्शन के पैकिंग पैरामीटर

def setstyle(**styles):
    for key, value in styles.iteritems():      # styles is a regular dictionary
        setattr(someobject, key, value)

यह आपको इस तरह फ़ंक्शन का उपयोग करने देता है:

setstyle(color="red", bold=False)

13
क्या kwarg सिर्फ एक चर नाम है? तो मैं डीईएफ़ फंक (** आर्ग्स) का उपयोग कर सकता हूं: और यह काम करेगा?
श्रीराम

11
@ श्रीराम: सही है। तारांकन महत्वपूर्ण हैं। kwargs सिर्फ एक नाम है जो इसे देता है अगर कोई बेहतर नहीं है। (आमतौर पर वहाँ है।)
जॉर्ज शॉली

54
@Sriram: पठनीयता खातिर आप के लिए छड़ी चाहिए kwargs - अन्य प्रोग्रामर यह की सराहना करेंगे।
जोहंदोदो

12
** do unpack dictionaries.>> मन उड़ा / बेशक! उस बिट को समझाने के लिए +1।
मार्क

13
नोट: .iteritems()इसका नाम बदलकर .items()पाइथन 3 कर दिया गया है
fnkr

67

kwargs सिर्फ एक शब्दकोश है जो मापदंडों में जोड़ा जाता है।

एक शब्दकोश में कुंजी, मूल्य जोड़े हो सकते हैं। और वो हैं कंवर। ठीक है, यह कैसे है।

जो इतना आसान नहीं है।

उदाहरण के लिए (बहुत काल्पनिक) आपके पास एक इंटरफ़ेस है जो काम करने के लिए अन्य रूटीन को कॉल करता है:

def myDo(what, where, why):
   if what == 'swim':
      doSwim(where, why)
   elif what == 'walk':
      doWalk(where, why)
   ...

अब आपको एक नया तरीका "ड्राइव" मिलेगा:

elif what == 'drive':
   doDrive(where, why, vehicle)

लेकिन एक मिनट रुको, एक नया पैरामीटर "वाहन" है - आप इसे पहले नहीं जानते थे। अब आपको इसे myDo-function के हस्ताक्षर में जोड़ना होगा।

यहाँ आप kwargs को खेल में फेंक सकते हैं - आप केवल हस्ताक्षर में kwargs जोड़ सकते हैं:

def myDo(what, where, why, **kwargs):
   if what == 'drive':
      doDrive(where, why, **kwargs)
   elif what == 'swim':
      doSwim(where, why, **kwargs)

इस तरह से आपको अपने इंटरफ़ेस फ़ंक्शन के हस्ताक्षर को बदलने की आवश्यकता नहीं है, जब भी आपकी कुछ नियमित दिनचर्या बदल सकती है।

यह सिर्फ एक अच्छा उदाहरण है जो आपको क्वार्स मददगार मिल सकता है।


46

इस आधार पर कि एक अच्छा नमूना कभी-कभी एक लंबे प्रवचन से बेहतर होता है मैं सभी अजगर चर तर्क पासिंग सुविधाओं (पोजिशन और नामित तर्क दोनों) का उपयोग करके दो फ़ंक्शन लिखूंगा। आपको आसानी से यह देखने में सक्षम होना चाहिए कि यह अपने आप से क्या करता है:

def f(a = 0, *args, **kwargs):
    print("Received by f(a, *args, **kwargs)")
    print("=> f(a=%s, args=%s, kwargs=%s" % (a, args, kwargs))
    print("Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)")
    g(10, 11, 12, *args, d = 13, e = 14, **kwargs)

def g(f, g = 0, *args, **kwargs):
    print("Received by g(f, g = 0, *args, **kwargs)")
    print("=> g(f=%s, g=%s, args=%s, kwargs=%s)" % (f, g, args, kwargs))

print("Calling f(1, 2, 3, 4, b = 5, c = 6)")
f(1, 2, 3, 4, b = 5, c = 6)

और यहाँ उत्पादन है:

Calling f(1, 2, 3, 4, b = 5, c = 6)
Received by f(a, *args, **kwargs) 
=> f(a=1, args=(2, 3, 4), kwargs={'c': 6, 'b': 5}
Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)
Received by g(f, g = 0, *args, **kwargs)
=> g(f=10, g=11, args=(12, 2, 3, 4), kwargs={'c': 6, 'b': 5, 'e': 14, 'd': 13})

28

मूल भाव: *argsऔर **kwargsतर्क है कि जरूरत एक समारोह कॉल करने के लिए प्रदान किया जाने वाला के लिए एक प्लेसहोल्डर रूप में कार्य करता

फ़ंक्शन का उपयोग करना *argsऔर **kwargsकॉल करना

def args_kwargs_test(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

अब हम *argsउपरोक्त परिभाषित फ़ंक्शन को कॉल करने के लिए उपयोग करेंगे

#args can either be a "list" or "tuple"
>>> args = ("two", 3, 5)  
>>> args_kwargs_test(*args)

परिणाम:

arg1: दो
arg2: 3
arg3: 5


अब, **kwargsउसी फ़ंक्शन को कॉल करने के लिए उपयोग करना

#keyword argument "kwargs" has to be a dictionary
>>> kwargs = {"arg3":3, "arg2":'two', "arg1":5}
>>> args_kwargs_test(**kwargs)

परिणाम:

arg1: 5
arg2: दो
arg3: 3

बॉटमलाइन: *argsकोई बुद्धिमत्ता नहीं है, यह केवल पारित आरों को मापदंडों (बाएं-से-दाएं क्रम में) को प्रक्षेपित **kwargsकरता है जबकि उचित मूल्य @ आवश्यक स्थान पर रखकर बुद्धिमानी से व्यवहार करता है


24
  • kwargsमें **kwargsसिर्फ चर नाम है। आप बहुत अच्छी तरह से कर सकते हैं**anyVariableName
  • kwargs"खोजशब्द तर्क" के लिए खड़ा है। लेकिन मुझे लगता है कि उन्हें "नामित तर्कों" के रूप में बेहतर कहा जाना चाहिए, क्योंकि ये केवल नामों के साथ पारित किए गए तर्क हैं (मुझे शब्द "तर्कों" शब्द में "कीवर्ड" के लिए कोई महत्व नहीं मिलता है। मुझे लगता है कि "कीवर्ड" का अर्थ आमतौर पर होता है) प्रोग्रामिंग भाषा द्वारा आरक्षित शब्द और इसलिए इसका उपयोग प्रोग्रामर द्वारा चर नामों के लिए नहीं किया जा सकता है। ऐसा कोई भी काम नहीं हो रहा है। तो हम फ़ंक्शन को नाम param1और param2दो पैरामीटर मान इस प्रकार देते हैं: func(param1="val1",param2="val2")केवल मानों को पारित करने के बजाय func(val1,val2):। इस प्रकार, मुझे लगता है कि उन्हें उचित रूप से "नामित तर्कों की मनमानी संख्या" कहा जाना चाहिए क्योंकि हम इनमें से किसी भी संख्या को निर्दिष्ट कर सकते हैं (funcfunc(**kwargs)

इसलिए कहा जा रहा है कि मुझे "नामित तर्कों" को पहले समझाएं और फिर "नामित तर्कों की मनमानी संख्या" kwargs

नामित तर्क

  • नामित आर्गों को स्थैतिक आर्ग का पालन करना चाहिए
  • नामित आर्ग का क्रम महत्वपूर्ण नहीं है
  • उदाहरण

    def function1(param1,param2="arg2",param3="arg3"):
        print("\n"+str(param1)+" "+str(param2)+" "+str(param3)+"\n")
    
    function1(1)                      #1 arg2 arg3   #1 positional arg
    function1(param1=1)               #1 arg2 arg3   #1 named arg
    function1(1,param2=2)             #1 2 arg3      #1 positional arg, 1 named arg
    function1(param1=1,param2=2)      #1 2 arg3      #2 named args       
    function1(param2=2, param1=1)     #1 2 arg3      #2 named args out of order
    function1(1, param3=3, param2=2)  #1 2 3         #
    
    #function1()                      #invalid: required argument missing
    #function1(param2=2,1)            #invalid: SyntaxError: non-keyword arg after keyword arg
    #function1(1,param1=11)           #invalid: TypeError: function1() got multiple values for argument 'param1'
    #function1(param4=4)              #invalid: TypeError: function1() got an unexpected keyword argument 'param4'

नामित तर्कों की संख्या के विपरीत kwargs

  • समारोह मापदंडों की अनुक्रम:
    1. स्थिति संबंधी मापदंड
    2. औपचारिक मानदंड तर्कों की संख्या पर कब्जा कर रहा है (* के साथ उपसर्ग)
    3. औपचारिक पैरामीटर नाम
    4. नामांकित मापदंडों की मनमानी संख्या पर कब्जा करने वाला औपचारिक पैरामीटर (पूर्व के साथ **)
  • उदाहरण

    def function2(param1, *tupleParams, param2, param3, **dictionaryParams):
        print("param1: "+ param1)
        print("param2: "+ param2)
        print("param3: "+ param3)
        print("custom tuple params","-"*10)
        for p in tupleParams:
            print(str(p) + ",")
        print("custom named params","-"*10)
        for k,v in dictionaryParams.items():
            print(str(k)+":"+str(v))
    
    function2("arg1",
              "custom param1",
              "custom param2",
              "custom param3",
              param3="arg3",
              param2="arg2", 
              customNamedParam1 = "val1",
              customNamedParam2 = "val2"
              )
    
    # Output
    #
    #param1: arg1
    #param2: arg2
    #param3: arg3
    #custom tuple params ----------
    #custom param1,
    #custom param2,
    #custom param3,
    #custom named params ----------
    #customNamedParam2:val2
    #customNamedParam1:val1

कस्टम args के लिए गुदगुदी और तानाशाह चर रहा है

इसे खत्म करने के लिए, मुझे यह भी ध्यान देना चाहिए कि हम पास हो सकते हैं

  • "औपचारिक पैरामीटर तर्कों की मनमानी संख्या पर कब्जा कर रहा है" टपल चर के रूप में और
  • "औपचारिक पैरामीटर नामित पैरामीटर्स की मनमानी संख्या को कैप्चर करता है"

इस प्रकार उपरोक्त कॉल को इस प्रकार बनाया जा सकता है:

tupleCustomArgs = ("custom param1", "custom param2", "custom param3")
dictCustomNamedArgs = {"customNamedParam1":"val1", "customNamedParam2":"val2"}

function2("arg1",
      *tupleCustomArgs,    #note *
      param3="arg3",
      param2="arg2", 
      **dictCustomNamedArgs     #note **
      )

अंत में ध्यान दें *और **फ़ंक्शन कॉल में। यदि हम उन्हें छोड़ देते हैं, तो हमें बुरे परिणाम मिल सकते हैं।

*टपल आर्गन में ओमिटिंग:

function2("arg1",
      tupleCustomArgs,   #omitting *
      param3="arg3",
      param2="arg2", 
      **dictCustomNamedArgs
      )

प्रिंट

param1: arg1
param2: arg2
param3: arg3
custom tuple params ----------
('custom param1', 'custom param2', 'custom param3'),
custom named params ----------
customNamedParam2:val2
customNamedParam1:val1

ऊपर के ('custom param1', 'custom param2', 'custom param3')रूप में मुद्रित किया जाता है।

नमस्कार dictआर्ग:

function2("arg1",
      *tupleCustomArgs,   
      param3="arg3",
      param2="arg2", 
      dictCustomNamedArgs   #omitting **
      )

देता है

dictCustomNamedArgs
         ^
SyntaxError: non-keyword arg after keyword arg

3
मुझे लगता है कि keywordशब्दावली इस तथ्य से आती है कि आप एक तानाशाही में गुजर रहे हैं जो कि-वैल्यू जोड़े का एक डेटाबेस है।
कोबरा

क्या आप का अर्थ है "कुंजी" शब्द "की" -युगल जोड़े में? इसके अलावा आमतौर पर डेटाबेस नहीं कहा जाता है, लेकिन शब्दकोश। लेकिन अभी भी शब्द "कीवर्ड" के उपयोग के लिए कोई महत्व नहीं पा रहा है।
महेश 999

9

इसके अतिरिक्त, आप kwargs फ़ंक्शन को कॉल करते समय उपयोग के विभिन्न तरीकों को भी मिला सकते हैं:

def test(**kwargs):
    print kwargs['a']
    print kwargs['b']
    print kwargs['c']


args = { 'b': 2, 'c': 3}

test( a=1, **args )

यह आउटपुट देता है:

1
2
3

ध्यान दें कि ** kwargs को अंतिम तर्क होना चाहिए


5

kwargs नाम के तर्कों को डिक्शनरी के रूप में पारित करने के लिए एक सिन्गनेटिक शुगर है (func के लिए), या डिस्क्लेमर को तर्क के रूप में नाम दिया जाता है (funk के लिए)


5

यहाँ एक सरल कार्य है जो उपयोग की व्याख्या करता है:

def print_wrap(arg1, *args, **kwargs):
    print(arg1)
    print(args)
    print(kwargs)
    print(arg1, *args, **kwargs)

फ़ंक्शन परिभाषा में निर्दिष्ट नहीं किए गए किसी भी तर्क को argsसूची या सूची में रखा जाएगा kwargs, जो इस बात पर निर्भर करता है कि वे कीवर्ड तर्क हैं या नहीं:

>>> print_wrap('one', 'two', 'three', end='blah', sep='--')
one
('two', 'three')
{'end': 'blah', 'sep': '--'}
one--two--threeblah

यदि आप एक ऐसा कीवर्ड तर्क जोड़ते हैं जो कभी किसी फ़ंक्शन में नहीं जाता है, तो एक त्रुटि उठाई जाएगी:

>>> print_wrap('blah', dead_arg='anything')
TypeError: 'dead_arg' is an invalid keyword argument for this function

1

यहाँ एक उदाहरण है जो मुझे आशा है कि सहायक है:

#! /usr/bin/env python
#
def g( **kwargs) :
  print ( "In g ready to print kwargs" )
  print kwargs
  print ( "in g, calling f")
  f ( **kwargs )
  print ( "In g, after returning from f")

def f( **kwargs ) :
  print ( "in f, printing kwargs")
  print ( kwargs )
  print ( "In f, after printing kwargs")


g( a="red", b=5, c="Nassau")

g( q="purple", w="W", c="Charlie", d=[4, 3, 6] )

जब आप प्रोग्राम चलाते हैं, तो आपको मिलता है:

$ python kwargs_demo.py 
In g ready to print kwargs
{'a': 'red', 'c': 'Nassau', 'b': 5}
in g, calling f
in f, printing kwargs
{'a': 'red', 'c': 'Nassau', 'b': 5}
In f, after printing kwargs
In g, after returning from f
In g ready to print kwargs
{'q': 'purple', 'c': 'Charlie', 'd': [4, 3, 6], 'w': 'W'}
in g, calling f
in f, printing kwargs
{'q': 'purple', 'c': 'Charlie', 'd': [4, 3, 6], 'w': 'W'}
In f, after printing kwargs
In g, after returning from f

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


0

यह अजगर अनपैकिंग के बारे में समझने के लिए सरल उदाहरण है ,

>>> def f(*args, **kwargs):
...    print 'args', args, 'kwargs', kwargs

EG1:

>>>f(1, 2)
>>> args (1,2) kwargs {} #args return parameter without reference as a tuple
>>>f(a = 1, b = 2)
>>> args () kwargs {'a': 1, 'b': 2} #args is empty tuple and kwargs return parameter with reference as a dictionary

0

जावा में, आप निर्माणकर्ताओं का उपयोग कक्षाओं को अधिभार करने के लिए करते हैं और कई इनपुट मापदंडों के लिए अनुमति देते हैं। अजगर में, आप समान व्यवहार प्रदान करने के लिए क्वार्ग्स का उपयोग कर सकते हैं।

जावा उदाहरण: https://beginnersbook.com/2013/05/constructor-overloading/

अजगर का उदाहरण:

class Robot():
    # name is an arg and color is a kwarg
    def __init__(self,name, color='red'):
        self.name = name
        self.color = color

red_robot = Robot('Bob')
blue_robot = Robot('Bob', color='blue')

print("I am a {color} robot named {name}.".format(color=red_robot.color, name=red_robot.name))
print("I am a {color} robot named {name}.".format(color=blue_robot.color, name=blue_robot.name))

>>> I am a red robot named Bob.
>>> I am a blue robot named Bob.

इसके बारे में सोचने का दूसरा तरीका।


0

कीवर्ड तर्क अक्सर पायथन में kwargs के लिए छोटा कर दिया जाता है । में कंप्यूटर प्रोग्रामिंग ,

कीवर्ड तर्क फ़ंक्शन कॉल के लिए एक कंप्यूटर भाषा के समर्थन को संदर्भित करते हैं जो फ़ंक्शन कॉल के भीतर प्रत्येक पैरामीटर के नाम को स्पष्ट रूप से बताता है।

पैरामीटर नाम ** kwargs से पहले दो तारांकन का उपयोग होता है , जब कोई यह नहीं जानता है कि फ़ंक्शन में कितने कीवर्ड तर्क दिए जाएंगे। जब ऐसा होता है, तो इसे आर्बिटवर्स / वाइल्डकार्ड कीवर्ड तर्क कहा जाता है।

इसका एक उदाहरण Django के रिसीवर फ़ंक्शन हैं

def my_callback(sender, **kwargs):
    print("Request finished!")

ध्यान दें कि फ़ंक्शन वाइल्डकार्ड कीवर्ड तर्क (** kwargs) के साथ एक प्रेषक तर्क लेता है; सभी सिग्नल हैंडलर को ये तर्क देने होंगे। सभी सिग्नल कीवर्ड तर्क भेजते हैं, और किसी भी समय वे कीवर्ड तर्क बदल सकते हैं। Request_finished के मामले में , यह बिना किसी तर्क के भेजने के रूप में प्रलेखित है, जिसका अर्थ है कि हमें my_callback (प्रेषक) के रूप में हमारे सिग्नल हैंडलिंग को लिखने के लिए लुभाया जा सकता है।

यह गलत होगा - वास्तव में, यदि आप ऐसा करते हैं तो Django एक त्रुटि फेंक देगा। ऐसा इसलिए है क्योंकि किसी भी बिंदु पर तर्क सिग्नल में जुड़ सकते हैं और आपका रिसीवर उन नए तर्कों को संभालने में सक्षम होना चाहिए।

ध्यान दें कि इसे kwargs नहीं कहा जाना चाहिए , लेकिन इसके लिए ** ( kwargs नाम एक सम्मेलन है) की आवश्यकता है।

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