2011-05-02 21 views
6

क्या यह लिखने का एक और अधिक शानदार तरीका है?स्थानीय चर नाम फ़ंक्शन पैरामीटर नाम के समान होते हैं

f(a=a, b=b, c=c, d=d, e=e) 

पृष्ठभूमि: मैं भी कई तर्क

f(a, b, c, d, e): 
    pass 

के साथ एक समारोह है मैं अपने कार्यक्रम मैं स्थानीय चर कि समारोह पैरामीटर के रूप में बिल्कुल एक ही नाम दिया जाता है।

a, b, c, d, e = range(5) 

मैं कीवर्ड तर्क के साथ फ़ंक्शन को कॉल करना चाहता हूं। चूंकि चर का नाम समान है, इस प्रकार कॉल दिखाई देगी।

g = f(a=a, b=b, c=c, d=d, e=e) # this can get very long 
बेशक

, मैं इस उदाहरण में स्थिति कीवर्ड का नहीं इस

g = f(a, b, c, d, e) 

लेकिन a, b, c, d, e की तरह बस चर के नाम का उपयोग कर रहे aruguments गुजरती हैं और यह कर सकते हैं सही क्रम देखने में आसान है। हालांकि दुर्भाग्यवश मेरे कार्यक्रम में चर को अधिक जटिल रूप से नामित किया गया है और कोई आसानी से स्पष्ट प्राकृतिक आदेश नहीं है। इसलिए मैं वास्तव में किसी भी गलतियों से बचने के लिए उन्हें कीवर्ड द्वारा पास करना चाहता हूं।

उत्तर

5

आप निम्न की तरह कुछ कर सकता है:

a, b, c, d, e = range(5) 
arg_dict = lambda l: dict((k, globals()[k]) for k in l.split(', ')) 

arg_dict('a, b, c, d, e') => {'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3} है, तो आप इस तरह अपने फ़ंक्शन को कॉल कर सकते हैं:

f(**arg_dict('a, b, c, d, e')) 

यह आपको निर्दिष्ट करने के लिए वास्तव में कौन-चर आप करना चाहते हैं की क्षमता देता है उपयोग। इसके लिए एक वैकल्पिक तरीका globals() का उपयोग नहीं करेगा eval() का उपयोग करना होगा, लेकिन यह लैम्ब्डा का संभावित रूप से असुरक्षित उपयोग कर सकता है।

arg_dict = lambda l: dict(zip(l.split(', '), eval(l))) 

आप के बजाय लैम्ब्डा में globals() का उपयोग कर आप निम्नलिखित का उपयोग कर सकते की एक तर्क के रूप में locals() पारित करने के लिए पसंद करेंगे, तो:

arg_dict = lambda l, d=locals(): dict((k, d[k]) for k in l.split(', ')) 
f(**arg_dict('a, b, c, d, e')) 

locals() सुझाव के लिए senderle के लिए धन्यवाद।

+0

मामूली बिंदु: क्या यह 'स्थानीय' नहीं होना चाहिए? – senderle

+0

'लैम्ब्डा' का अपना दायरा है, इसलिए इसके दायरे से स्थानीय चर 'लोकल()' में नहीं हैं यदि इसका प्रयोग लैम्ब्डा के अंदर किया जाता है (लेकिन वे 'ग्लोबल्स() 'में होंगे)। –

+0

वंडरबार! यही वह है जिसकी तलाश में मैं हूं। धन्यवाद! मैं @sendle से सहमत हूं कि मैं 'ग्लोबल्स()' के बजाय 'स्थानीय()' का उपयोग कर सकता हूं। –

1

आप यहां ** किलोवाट का उपयोग क्यों नहीं कर सकते?

def foo(**kw): 
    for k,v in kw.items(): 
     print k,v 


foo(a=2) 
foo(a=3, b=4) 
foo(nonsene=True, blather=False) 
+0

मैं मानता हूं कि यह प्राकृतिक विकल्प होगा। हालांकि, foo() को बाहरी मॉड्यूल में परिभाषित किया गया है और मेरे पास इस पर नियंत्रण नहीं है कि फ़ंक्शन को कैसे परिभाषित किया गया है। –

+0

एक विकल्प बार() को foo() के लिए एक रैपर के रूप में परिभाषित करना है और तर्कों को पास करता है, लेकिन मैं सोच रहा था कि कोई आसान तरीका है या नहीं। –

1

locals() अपने स्थानीय चर देता है, तो आप

def somewhere(): 
    x = 3 # its a local 
    f(**locals()) # same as f(x=3) 

कर सकता है, लेकिन आप निश्चित रूप से देख सकते हैं कि यह कैसे बहुत नाजुक है।

+0

मैं स्थानीय लोगों के बारे में भी सोच रहा था। लेकिन यह हल करने के लिए 'सुरुचिपूर्ण' तरीका नहीं लग रहा था। अगर सब विफल हो जाते हैं, तो मुझे ब्रूट फोर्स के साथ रहना चाहिए!:) –