2011-07-05 9 views
5

में कीवर्ड तर्क के रूप में स्थितित्मक तर्कों का इलाज कैसे कर सकता हूं एक सजावट के लिए मैं लिख रहा हूं, मैं एक फ़ंक्शन के विशिष्ट नामित पैरामीटर में हेरफेर करना चाहता हूं। ,मैं पाइथन 2

>>> quotient(dividend=2) 
4 

लेकिन जब के रूप में दिया:

def square_param(param): 
    def func_decorator(func): 
     def func_caller(*args,**kwargs): 
      kwargs[param] = kwargs[param] * kwargs[param] 
      return func(*args,**kwargs) 
    return func_caller 
return func_decorator 

एप्लाइड अगले समारोह पर: निम्नलिखित डेकोरेटर पर विचार करें

@square_param('dividend') 
def quotient(divisor=1,dividend=0): 
    return dividend/divisor 

यह कार्य करेगा जब लाभांश एक कीवर्ड तर्क जैसे के रूप में कहा जाता है एक स्थितित्मक तर्क यह असफल हो जाएगा।

>>> quotient(3,4) 
TypeError: quotient() got multiple values for keyword argument 'dividend' 

अजगर 3 के साथ मैं पैरामीटर मजबूर कर इस का समाधान कर सकता always given as a keyword होने के लिए:

@square_param('dividend') 
def quotient(divisor=1,*,dividend=0): 
    return dividend/divisor 

लेकिन मैं अजगर 2 का समर्थन करना चाहते हैं और यह भी मैं समारोह पर कम से कम प्रतिबंध लगाने के लिए चाहते हैं ।

क्या कोई तरीका है कि मैं अपने सजावट में इस व्यवहार को ठीक कर सकता हूं?

+3

निरीक्षण मॉड्यूल का निरीक्षण करें। इसके लिए आपको इसकी आवश्यकता हो सकती है। Getargspec पर एक नज़र डालें। – Dirk

उत्तर

3

सबसे पहले, आपके square_param सजावटी काम नहीं करते क्योंकि यह फ़ंक्शन वापस नहीं करता है। यह होने की जरूरत है:

def square_param(param): 
    def func_decorator(func): 
     def func_caller(*args,**kwargs): 
      kwargs[param] = kwargs[param] * kwargs[param] 
      return func(*args,**kwargs) 
     return func_caller 
    return func_decorator 

अब मैं @ एक प्रकार की कटार की सलाह मान ली और inspect मॉड्यूल में देखा। आप पहले जांच कर ऐसा कर सकते हैं कि पैरामीटर फ़ंक्शन के स्थितित्मक तर्कों में से एक है, और दूसरा यदि वह स्थितित्मक तर्क निर्दिष्ट किया गया है, और उसके बाद उस तर्क स्थिति को संशोधित किया गया है। आपको यह सुनिश्चित करने की भी आवश्यकता है कि पैरामीटर को कीवर्ड तर्क के रूप में आपूर्ति किए जाने पर आप केवल kwargs को संशोधित करें।

import inspect 

def square_param(param): 
    def func_decorator(func): 
     def func_caller(*args,**kwargs): 
      funparams = inspect.getargspec(func).args 
      if param in funparams: 
       i = funparams.index(param) 
       if len(args) > i: 
        args = list(args) # Make mutable 
        args[i] = args[i] * args[i] 
      if param in kwargs: 
       kwargs[param] = kwargs[param] * kwargs[param] 
      return func(*args,**kwargs) 
     return func_caller 
    return func_decorator 
+0

धन्यवाद, यह वही है जो मैं ढूंढ रहा था! कार्यों की वापसी के बारे में, यह वास्तव में इस उदाहरण में बनाई गई एक छोटी बेवकूफ त्रुटि थी। –

2

भी निरीक्षण हम समारोह प्राप्त कर सकते हैं का उपयोग किए बिना पैरामीटर

>>> func = lambda x, y, args: (x, y, {}) 
>>> func.func_code.co_argcount 
3 
>>> func.func_code.co_varnames 
('x', 'y', 'args') 
+0

धन्यवाद! क्या आप शायद एक लिंक जोड़ सकते हैं जहां func_code सदस्यों को दस्तावेज किया गया है? मुझे वह नहीं मिल रहा है। –

+0

आपका स्वागत है! "func_code संकलित फ़ंक्शन बॉडी का प्रतिनिधित्व करने वाली कोड ऑब्जेक्ट है।" अधिक जानकारी के लिए आप [link] (http://docs.python.org/reference/datamodel.html) पर "कॉल करने योग्य प्रकार" अनुभाग देख सकते हैं। – Yajushi

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