2010-02-10 15 views
8

पायथन में अपवाद उठाए बिना उपरोक्त कोड होना संभव है?क्या तर्क के बिना कोई फ़ंक्शन घोषित करना संभव है लेकिन फिर अपवाद को उठाए बिना उस फ़ंक्शन में कुछ तर्क पारित करना संभव है?

def myfunc(): 
    pass 

# TypeError myfunc() takes no arguments (1 given) 
myfunc('param') 

आमतौर पर कुछ परिस्थितियों में php में मैं पैरामीटर के बिना एक समारोह का शुभारंभ और फिर समारोह के अंदर मानकों को पुनः प्राप्त।

प्रैक्टिस में मैं myfunc में तर्क घोषित नहीं करना चाहता हूं और उसके बाद कुछ तर्क पारित करना चाहता हूं। मुझे मिला एकमात्र समाधान myfunc(*arg) है। क्या कोई और तरीका है?

+9

क्यों 'myfunc (* आर्ग)' नहीं अच्छा पर्याप्त है? – interjay

+3

मैं अनुमान लगा रहा हूं कि यूरी (अभी तक) * arg – Dana

+0

के बारे में पता नहीं है कार्यान्वयन को myfunc को किसी अन्य फ़ंक्शन पर कॉलबैक होने की आवश्यकता है जो इसे एक तर्क समझने वाली सूची समझ में कॉल करने का प्रयास करता है। इसलिए मेरे पास कॉलबैक कार्यान्वयन पर नियंत्रण नहीं है और उपयोगकर्ता जानबूझकर '* args' को छोड़ नहीं सकता (कोड में मैं इस घटना के बारे में परवाह करता हूं) – yuri

उत्तर

10
>>> def myFunc(*args, **kwargs): 
... # This function accepts arbitary arguments: 
... # Keywords arguments are available in the kwargs dict; 
... # Regular arguments are in the args tuple. 
... # (This behaviour is dictated by the stars, not by 
... # the name of the formal parameters.) 
... print args, kwargs 
... 
>>> myFunc() 
() {} 
>>> myFunc(2) 
(2,) {} 
>>> myFunc(2,5) 
(2, 5) {} 
>>> myFunc(b = 3) 
() {'b': 3} 
>>> import dis 
>>> dis.dis(myFunc) 
    1   0 LOAD_FAST    0 (args) 
       3 PRINT_ITEM 
       4 LOAD_FAST    1 (kwargs) 
       7 PRINT_ITEM 
       8 PRINT_NEWLINE 
       9 LOAD_CONST    0 (None) 
      12 RETURN_VALUE 

और वास्तव में सवाल का जवाब देने: नहीं, मैं नहीं मानता कि वहाँ अन्य तरीके हैं।

मुख्य कारण बहुत आसान है: सी पायथन स्टैक आधारित है। एक फ़ंक्शन जिसमें पैरामीटर की आवश्यकता नहीं होती है, उसमें स्टैक (myFunc) के लिए आवंटित स्थान नहीं होगा, इसके बजाय, उन्हें स्थिति 0 और 1 में रखा जाएगा)। (टिप्पणियां देखें)

एक अतिरिक्त बिंदु यह है कि आप अन्यथा पैरामीटर कैसे एक्सेस करेंगे?

+2

स्टैक टिप्पणी बिंदु के अलावा है। पायथन स्टैक-आधारित है, लेकिन बहस (और पार्सिंग) तर्क नहीं है (तर्क हमेशा स्टैक पर एक ही आइटम होते हैं, भले ही कोई तर्क न हो।) कारण Python तर्कों को अनदेखा नहीं करता है क्योंकि यह ** त्रुटियों को छुपाएगा **। –

+0

यह वास्तव में काफी संभव है कि मैं गलत कह रहा हूं कि मुझे क्या बताता है :) – badp

4

निश्चित रूप से कर सकते हैं!

तुम इतनी तरह चर लंबाई पैरामीटर सूचियां निर्धारित कर सकते हैं: (2 1) अपने कार्य के अंदर

foo(1,2) 

आप टपल देता है:

def foo(*args): 
    print len(args) 

आर्ग अपने मापदंडों के एक टपल तो बुला है ।

+0

'Args' वास्तव में एक tuple होगा। –

+0

ओह हाँ! फिक्स्ड! – Dana

11

वहाँ

में आर्ग पारित करने के लिए स्थिति के

>>> def myfunc(*args): 
... print "args", args 
... 
>>> myfunc("param") 
args ('param',) 

करके कीवर्ड

>>> def myfunc(**kw): 
... print "kw", kw 
... 
>>> myfunc(param="param") 
kw {'param': 'param'} 

दो तरीके हैं और तुम दोनों

के संयोजन का उपयोग कर सकते हैं
>>> def myfunc(*args, **kw): 
... print "args", args 
... print "kw", kw 
... 
>>> myfunc("param") 
args ('param',) 
kw {} 
>>> 
>>> myfunc(param="param") 
args() 
kw {'param': 'param'} 
>>> 
>>> myfunc("param", anotherparam="anotherparam") 
args ('param',) 
kw {'anotherparam': 'anotherparam'} 
1

यहाँ एक समारोह डेकोरेटर मैं सिर्फ इतना है कि ऐसा करने के लिए लिखा है उपयोग का एक उदाहरण के साथ:

def IgnoreExtraArguments(f): 
    import types 
    c = f.func_code 
    if c.co_flags & 0x04 or c.co_flags&0x08: 
     raise ValueError('function already accepts optional arguments') 
    newc = types.CodeType(c.co_argcount, 
        c.co_nlocals, 
        c.co_stacksize, 
        c.co_flags | 0x04 | 0x08, 
        c.co_code, 
        c.co_consts, 
        c.co_names, 
        c.co_varnames+('_ignore_args','_ignore_kwargs'), 
        c.co_filename, 
        c.co_name, 
        c.co_firstlineno, 
        c.co_lnotab, 
        c.co_freevars, 
        c.co_cellvars) 
    f.func_code = newc 
    return f 

if __name__ == "__main__": 
    def f(x,y): 
     print x+y 

    g = IgnoreExtraArguments(f) 
    g(2,4) 
    g(2,5,'banana') 

    class C(object): 
     @IgnoreExtraArguments 
     def m(self,x,y): 
      print x-y 

    a=C() 
    a.m(3,5) 
    a.m(3,6,'apple') 
संबंधित मुद्दे

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