2012-06-16 5 views
16

मान लीजिए मैं एक समारोह है:Unpacking कीवर्ड तर्क है, लेकिन केवल जो कि समारोह से मेल

def foo(a = None, b=None, c=None): 
    return "a:%s, b:%s, c:%s" % (a,b,c) 

मैं ऊपर, लेकिन यह भी सुझाव दिए गए हैं कि साथ बहस में से कुछ (या कोई भी) के साथ एक शब्दकोश है समारोह में तर्क, जैसे नाम नहीं:

d = {'a':1, 'x':4, 'b':2, 'y':5} 

अगर मैं फोन निम्नलिखित मैं एक त्रुटि मिल जाएगा, क्योंकि 'एक्स' और 'y' foo समारोह में कीवर्ड तर्क नहीं हैं।

foo(**d) # error 

वहाँ एक समारोह के लिए एक शब्दकोश से तर्क गुजर की एक सुंदर तरीका है, लेकिन केवल चाबियाँ कि समारोह तर्क से मेल के साथ उन मूल्यों।

अगर मेरा तर्क/पैरामीटर शब्दावली बंद है तो कृपया मुझे सही करें।

उत्तर

7

@ अश्विनी चौधरी के पास आपकी समस्या को हल करने का एक बहुत ही पागल तरीका है। हालांकि, इसे आपके foo फ़ंक्शन के हस्ताक्षर को बदलने की आवश्यकता है।

आप अपने समारोह हस्ताक्षर बदलने के लिए नहीं करना चाहते हैं, तो आप पता लगाने के लिए क्या तर्क अपने कार्य की उम्मीद introspection उपयोग कर सकते हैं:

arg_count = foo.func_code.co_argcount 
args = foo.func_code.co_varnames[:arg_count] 

args_dict = {} 
for k, v in d.iteritems(): 
    if k in args: 
     args_dict[k] = v 

foo(**args_dict) 
28
def foo(a = None, b=None, c=None,**extras): 
    return "a:%s, b:%s, c:%s" % (a, b, c) 

यहां **extras सभी अतिरिक्त नाम/कीवर्ड तर्क एकत्रित करेंगे।

6

दिलचस्प सवाल है। मुझे लगता है कि वास्तविक जीवन में अधिकांश लोग @ अश्विनी चौधरी दृष्टिकोण का उपयोग करते हैं।

मैं @Rodrigue से सहमत हूं कि कई बार आप (किसी और का मॉड्यूल शायद) के कॉल हस्ताक्षर को संशोधित नहीं कर सकते हैं।

जब ऐसा होता है, एक समारोह डेकोरेटर

from inspect import getargspec 
from funtools import wraps 

def allow_kwargs(foo): 
    argspec = getargspec(foo) 
    # if the original allows kwargs then do nothing 
    if argspec.keywords: 
     return foo 
    @wraps(foo) 
    def newfoo(*args, **kwargs): 
     #print "newfoo called with args=%r kwargs=%r"%(args,kwargs) 
     some_args = dict((k,kwargs[k]) for k in argspec.args if k in kwargs) 
     return foo(*args, **some_args) 
    return newfoo 


# with your function: 
@allow_kwargs 
def foo(a = None, b=None, c=None): 
    return "a:%s, b:%s, c:%s " % (a,b,c) 

# with someone_elses function: 
from some_place import foo 
foo = allow_kwargs(foo) 

@wraps functools से चातुर्य में __name__ और __doc__ तार रहता है का उपयोग करें। आप यह भी कर सकते हैं:

  • सजावट मॉड्यूल से FunctionMaker पर देखें लेकिन यह एक और पुन: प्रयोज्य दृष्टिकोण होना चाहिए।
  • अतिरिक्त गैर कीवर्ड वर्रों को पारित करने की अनुमति देने के लिए newfoo को संशोधित करें।
संबंधित मुद्दे