python - * तर्क और** kwargs?
(8)
* तर्क और ** kwargs पाइथन की विशेष जादू विशेषताएं हैं। ऐसे फ़ंक्शन के बारे में सोचें जिसमें अज्ञात संख्या में तर्क हो सकते हैं। उदाहरण के लिए, जो भी कारणों से, आप ऐसा कार्य करना चाहते हैं जो संख्याओं की अज्ञात संख्या का योग करता है (और आप अंतर्निहित योग फ़ंक्शन का उपयोग नहीं करना चाहते हैं)। तो आप इस समारोह को लिखते हैं:
def sumFunction(*args):
result = 0
for x in args:
result += x
return result
और इसका उपयोग करें: sumFunction (3,4,6,3,6,8,9)।
** kwargs एक diffrent समारोह है। ** kwargs के साथ आप किसी फ़ंक्शन में मनमानी कीवर्ड तर्क दे सकते हैं और आप उन्हें एक तानाशाही के रूप में एक्सेस कर सकते हैं।
def someFunction(**kwargs):
if 'text' in kwargs:
print kwargs['text']
कुछ फ़ंक्शन को कॉल करना (टेक्स्ट = "foo") foo प्रिंट करेगा।
इस प्रश्न का उत्तर यहां दिया गया है:
तो मुझे *args
और **kwargs
की अवधारणा में कठिनाई है।
अब तक मैंने सीखा है कि:
-
*args
= तर्कों की सूची*args
तर्क के रूप में -
**kwargs
= शब्दकोश - जिनकी चाबियां अलग-अलग कीवर्ड तर्क बन जाती हैं और मान इन तर्कों के मान बन जाते हैं।
मुझे समझ में नहीं आता कि प्रोग्रामिंग कार्य किसके लिए उपयोगी होगा।
शायद:
मुझे सूचियों और शब्दकोशों को एक समारोह के तर्क के रूप में और साथ ही वाइल्डकार्ड के रूप में दर्ज करना लगता है, इसलिए मैं कोई भी तर्क पारित कर सकता हूं?
क्या यह बताने के लिए एक सरल उदाहरण है कि *args
और **kwargs
का उपयोग कैसे किया जाता है?
इसके अलावा मैंने पाया ट्यूटोरियल केवल "*" और एक चर नाम का उपयोग किया।
क्या *args
और **kwargs
केवल प्लेसहोल्डर हैं या आप कोड में बिल्कुल *args
और **kwargs
का उपयोग करते हैं?
आप पाइथन डॉक्स (FAQ में docs.python.org) पर एक नज़र डाल सकते हैं, लेकिन विशेष रूप से एक अच्छी व्याख्या के लिए रहस्यमय मिस Args और mister kwargs (archive.org की सौजन्य) (मूल, मृत लिंक यहां है )।
संक्षेप में, दोनों का उपयोग तब किया जाता है जब किसी फ़ंक्शन या विधि के वैकल्पिक पैरामीटर का उपयोग किया जाता है। जैसा कि डेव कहते हैं, * तर्क का उपयोग तब किया जाता है जब आप नहीं जानते कि कितने तर्क पारित किए जा सकते हैं, और ** जब आप नाम और मान द्वारा निर्दिष्ट पैरामीटर को संभालना चाहते हैं तो kwargs:
myfunction(myarg=1)
एक स्थान जहां *args
और **kwargs
का उपयोग उप-वर्गीकरण के लिए काफी उपयोगी है।
class Foo(object):
def __init__(self, value1, value2):
# do something with the values
print value1, value2
class MyFoo(Foo):
def __init__(self, *args, **kwargs):
# do something else, don't care about the args
print 'myfoo'
super(MyFoo, self).__init__(*args, **kwargs)
इस तरह आप फू कक्षा के व्यवहार को बढ़ा सकते हैं, बिना फू के बारे में बहुत कुछ जानना। यदि आप एक एपीआई प्रोग्रामिंग कर रहे हैं जो बदल सकता है तो यह काफी सुविधाजनक हो सकता है। MyFoo बस Foo क्लास में सभी तर्कों को पास करता है।
डेव वेबब के अंतिम उदाहरण के रूप में **
वाक्यविन्यास का उपयोग करने के लिए मेरे पसंदीदा स्थानों में से एक यहां दिया गया है:
mynum = 1000
mystr = 'Hello World!'
print "{mystr} New-style formatting is {mynum}x more fun!".format(**locals())
मुझे यकीन नहीं है कि नामों का उपयोग करने की तुलना में यह बहुत तेज़ है, लेकिन यह टाइप करना बहुत आसान है!
नाम *args
और **kwargs
या **kw
पूरी तरह से सम्मेलन द्वारा हैं। यह हमारे लिए एक-दूसरे के कोड को पढ़ने में आसान बनाता है
संरचना मॉड्यूल का उपयोग करते समय यह एक आसान है
struct.unpack()
एक tuple देता है जबकि struct.pack()
तर्कों की एक चर संख्या का उपयोग करता है। जब डेटा में हेरफेर करना होता है तो यह struck.pack()
उदाहरण के लिए एक tuple पास करने में सक्षम होना सुविधाजनक है।
tuple_of_data = struct.unpack(format_str, data)
... manipulate the data
new_data = struct.pack(format_str, *tuple_of_data)
इस क्षमता के बिना आपको लिखने के लिए मजबूर किया जाएगा
new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...)
जिसका अर्थ यह भी है कि अगर format_str बदलता है और ट्यूपल में परिवर्तन का आकार बदल जाता है, तो मुझे वापस जाना होगा और वास्तव में लंबी लाइन को संपादित करना होगा
बस कल्पना करें कि आपके पास कोई फ़ंक्शन है लेकिन आप पैरामीटर की संख्या को प्रतिबंधित नहीं करना चाहते हैं। उदाहरण:
>>> import operator
>>> def multiply(*args):
... return reduce(operator.mul, args)
फिर आप इस फ़ंक्शन का उपयोग इस प्रकार करते हैं:
>>> multiply(1,2,3)
6
or
>>> numbers = [1,2,3]
>>> multiply(*numbers)
6
ये पैरामीटर आमतौर पर प्रॉक्सी फ़ंक्शंस के लिए उपयोग किए जाते हैं, इसलिए प्रॉक्सी लक्ष्य फ़ंक्शन पर कोई इनपुट पैरामीटर पास कर सकता है।
def foo(bar=2, baz=5):
print bar, baz
def proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments
print x
foo(*args, **kwargs) # applies the "non-x" parameter to foo
proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo
proxy(6)# calls foo with its default arguments
proxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument
लेकिन चूंकि ये पैरामीटर वास्तविक पैरामीटर नाम छुपाते हैं, इसलिए उनसे बचना बेहतर होता है।
वाक्यविन्यास *
और **
। नाम *args
और **kwargs
केवल सम्मेलन द्वारा हैं, लेकिन इनका उपयोग करने की कोई कठोर आवश्यकता नहीं है।
आप *args
उपयोग करेंगे जब आप सुनिश्चित नहीं हैं कि आपके फ़ंक्शन में कितने तर्क पारित किए जा सकते हैं, यानी यह आपको अपने फ़ंक्शन में मनमानी संख्याओं के तर्कों को पारित करने की अनुमति देता है। उदाहरण के लिए:
>>> def print_everything(*args):
for count, thing in enumerate(args):
... print( '{0}. {1}'.format(count, thing))
...
>>> print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage
इसी तरह, **kwargs
आपको उन नामांकित तर्कों को संभालने की अनुमति देता है जिन्हें आपने पहले से परिभाषित नहीं किया है:
>>> def table_things(**kwargs):
... for name, value in kwargs.items():
... print( '{0} = {1}'.format(name, value))
...
>>> table_things(apple = 'fruit', cabbage = 'vegetable')
cabbage = vegetable
apple = fruit
आप इन्हें नामित तर्कों के साथ भी उपयोग कर सकते हैं। स्पष्ट तर्क पहले मान प्राप्त करते हैं और फिर बाकी सब कुछ *args
और **kwargs
। नामित तर्क सूची में पहले आते हैं। उदाहरण के लिए:
def table_things(titlestring, **kwargs)
आप दोनों एक ही फ़ंक्शन परिभाषा में भी उपयोग कर सकते हैं लेकिन *args
**kwargs
से पहले होना चाहिए।
फ़ंक्शन को कॉल करते समय आप *
और **
वाक्यविन्यास का भी उपयोग कर सकते हैं। उदाहरण के लिए:
>>> def print_three_things(a, b, c):
... print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c))
...
>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)
a = aardvark, b = baboon, c = cat
जैसा कि आप इस मामले में देख सकते हैं, यह आइटम की सूची (या ट्यूपल) लेता है और इसे अनपैक करता है। इसके द्वारा यह समारोह में तर्कों से मेल खाता है। बेशक, आप फ़ंक्शन परिभाषा में और फ़ंक्शन कॉल में *
दोनों हो सकते हैं।