2009-04-03 11 views
27

यह कुछ हद तक सामान्य ज्ञान है कि पायथन कार्यों में अधिकतम 256 तर्क हो सकते हैं। इस सीमा *args और **kwargs पर लागू होता है, तो क्या मुझे पता है उत्सुक हूँ है जब वे निम्नलिखित तरीके से unrolled कर रहे हैं:पायथन फ़ंक्शन में अधिकतम संख्या में तर्क क्या हैं?

items = [1,2,3,4,5,6] 

def do_something(*items): 
    pass 

मैं पूछता हूँ क्योंकि, परिकल्पित, वहाँ मामलों में जहां एक सूची से बड़ा 256 आइटम हो सकता है *args या **kwargs के सेट के रूप में अनियंत्रित हो जाता है।

उत्तर

21

WFM

>>> fstr = 'def f(%s): pass' % (', '.join(['arg%d' % i for i in range(5000)])) 
>>> exec(fstr) 
>>> f 
<function f at 0x829bae4> 

अद्यतन: दूसरी ओर

>>> exec 'f(' + ','.join(str(i) for i in range(5000)) + ')' 

Traceback (most recent call last): 
    File "<pyshell#63>", line 1, in <module> 
    exec 'f(' + ','.join(str(i) for i in range(5000)) + ')' 
    File "<string>", line 1 
SyntaxError: more than 255 arguments (<string>, line 1) 

इस काम करता है:: के रूप में ब्रायन देखा, सीमा बुला तरफ है

>>> f(*range(5000)) 
>>> 

निष्कर्ष: नहीं, यह लागू नहीं होता है अनियंत्रित तर्कों के लिए।

+0

ऐसा लगता है कि सीमा कॉलिंग पक्ष पर है। मैं कोशिश करता हूं कि 'f (' + ','। (I000) के लिए (str (i) में शामिल हों (+000)) + ')' – Brian

+0

"डब्लूएफएम"? डब्ल्यूटीएफ? .... –

+0

@ स्टेफन: * मेरे लिए काम करता है * –

1

मैंने 4000 वस्तुओं की सूची के लिए प्रयास किया, और यह काम किया। तो मुझे लगता है कि यह बड़े मूल्यों के लिए भी काम करेगा।

1

** kwargs के लिए, अगर मुझे अच्छी तरह याद है, तो यह एक शब्दकोश है। इसलिए इसकी कोई सीमा नहीं है।

* तर्क के लिए, मुझे इतना यकीन नहीं है, लेकिन मुझे लगता है कि यह एक टुपल या सूची है, इसलिए इसकी कोई सीमा नहीं है।

कोई सीमा नहीं, मेरा मतलब है स्मृति स्मृति को छोड़कर।

+0

हाँ * तर्क एक ट्यूपल है। –

5

यह स्रोत को संकलित करने में एक प्रतिबंध प्रतीत होता है, इसलिए शायद केवल तर्कों के लिए मौजूद होगा, न कि * args या ** kwargs में।

प्रासंगिक कोड ast.c में पाया जा सकता है:

if (nargs + nkeywords + ngens > 255) { 
    ast_error(n, "more than 255 arguments"); 
    return NULL; 
} 

लेकिन ध्यान दें कि इस ast_for_call में है, और इसलिए केवल बुला ओर करने के लिए applys। यानि परिभाषा के बजाए f(a,b,c,d,e...), हालांकि यह दोनों स्थिति (a,b,c,d) और keyword (a=1, b=2, c=3) शैली मानकों की गणना करेगा। वास्तविक *args और **kwargs पैरामीटर दिखते हैं कि उन्हें कॉलिंग पक्ष पर इन उद्देश्यों के लिए केवल एक तर्क के रूप में गिना जाना चाहिए।

20

सीमा इस प्रकार है कि संकलित बाइटकोड एक तर्क को स्थिति तर्क और/या कीवर्ड तर्कों के साथ कैसे कॉल करता है।

चिंता का बाइटकोड सेशन CALL_FUNCTION है जिसमें ओप_र्ग होता है जो 4 बाइट लंबाई में होता है, लेकिन दो कम से कम महत्वपूर्ण बाइट्स का उपयोग किया जाता है। उनमें से, सबसे महत्वपूर्ण बाइट स्टैक पर कीवर्ड तर्कों की संख्या का प्रतिनिधित्व करता है और कम से कम महत्वपूर्ण बाइट स्टैक पर स्थितित्मक तर्कों की संख्या को दर्शाता है। इसलिए, आपके पास अधिकतम 0xFF == 255 कीवर्ड तर्क या 0xFF == 255 स्थितित्मक तर्क हो सकते हैं।

यह सीमा * args और ** kwargs पर लागू नहीं होती है क्योंकि उस व्याकरण के साथ कॉल हस्ताक्षर के आधार पर बाइटकोड ops CALL_FUNCTION_VAR, CALL_FUNCTION_KW, और CALL_FUNCTION_VAR_KW का उपयोग करते हैं। इन ऑपोड्स के लिए, स्टैक में * तर्क और ** kwargs के लिए एक dict के लिए एक पुनरावर्तक होता है। ये आइटम सीधे रिसीवर को पास किए जाते हैं जो उन्हें आवश्यकतानुसार अनलॉक करता है।

+0

क्या यह एक सीपीथन कार्यान्वयन प्रतिबंध है, या यह पायथन का हिस्सा है? – EOL

+1

यह सीपीथॉन बाइटकोड का कार्यान्वयन विवरण है। –

+0

... वास्तव में। सीमा सीपीथॉन 3.7 के साथ जारी की जाएगी। – EOL

2

CPython एक कॉल में 255 स्पष्ट रूप से पारित कर दिया तर्कों की एक सीमा होती है: क्योंकि अजगर 3.5, जब तक CALL_FUNCTION opcode दोनों एन्कोड करने के लिए opcode तर्क अतिभारित

>>> def f(*args, **kwargs): pass 
... 
>>> exec("f({})".format(', '.join(map(str, range(256))))) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<string>", line 1 
SyntaxError: more than 255 arguments 

यह सीमा जगह में है। स्टैक पर स्थितित्मक और कीवर्ड तर्कों की संख्या, दोनों एक बाइट में एन्कोडेड।

यह सीमा आगामी पायथन 3.7 रिलीज में हटा दी गई है, issue #27213 और issue #12844 देखें; # 27213 ने प्रदर्शन और सादगी (3.6 का हिस्सा) के लिए ऑपकोड के CALL_FUNCTION* परिवार को फिर से काम किया, केवल एक ही तर्क गणना को एन्कोड करने के लिए ऑपोड तर्क को मुक्त किया, और # 12844 संकलन-समय जांच को हटा दिया जिसने अधिक तर्कों के साथ कोड को संकलित करने से रोक दिया। , को बचाने के लिए कितने ढेर (ताकि अपनी स्मृति से अब बाध्य) पर लगाया जा सकता है

3.7 में, EXTENDED_ARG() opcode के साथ, वहाँ अब है कितने तर्क आप स्पष्ट तर्कों का उपयोग में पारित कर सकते हैं पर सभी पर कोई सीमा नहीं:

>>> import sys 
>>> sys.version_info 
sys.version_info(major=3, minor=7, micro=0, releaselevel='alpha', serial=2) 
>>> def f(*args, **kwargs): pass 
... 
>>> exec("f({})".format(', '.join(map(str, range(256))))) 
>>> exec("f({})".format(', '.join(map(str, range(2 ** 16))))) 

ध्यान दें कि सूचीबद्ध करता है, tuples और शब्दकोशों sys.maxsize तत्वों तक ही सीमित हैं, इसलिए यदि बुलाया समारोह *args का उपयोग करता है और/या **kwargs पकड़ने के सभी मापदंडों तो उन सीमित हैं मत करो।

*args और **kwargs कॉल सिंटैक्स (तर्कों का विस्तार) के लिए पाइथन मानक प्रकारों पर sys.maxint आकार सीमा के अलावा कोई सीमा नहीं है।

+0

अच्छी ताज़ा उत्तर नई जानकारी और संदर्भ प्रदान करते हैं – Rookie

संबंधित मुद्दे