2013-02-07 41 views
42

क्या पाइथन में यह जांचने का कोई आसान तरीका है कि वैकल्पिक पैरामीटर का मान उसके डिफ़ॉल्ट मान से आता है या उपयोगकर्ता ने इसे स्पष्ट रूप से फ़ंक्शन कॉल पर सेट किया है?पायथन: वैकल्पिक फ़ंक्शन पैरामीटर सेट किया गया है या नहीं, यह जांचने के लिए कि

+2

इससे कोई फर्क क्यों पड़ता है? – Volatility

+9

क्योंकि मैं इसे निश्चित रूप से उस कार्य में देखना चाहता हूं :) – Matthias

+0

बस 'none' को डिफ़ॉल्ट के रूप में उपयोग करें और इसके लिए जांचें।यदि आप वास्तव में इस परीक्षा को स्थापित कर सकते हैं, तो आप उपयोगकर्ता को डिफ़ॉल्ट व्यवहार को आमंत्रित करने वाले मान को स्पष्ट रूप से पास करने के लिए किसी भी संभावना को भी बहिष्कृत करेंगे। –

उत्तर

32

वास्तव में नहीं। मानक तरीका एक डिफ़ॉल्ट मान का उपयोग करना है जिसे उपयोगकर्ता को पास होने की उम्मीद नहीं की जाएगी, उदा। एक object उदाहरण:

DEFAULT = object() 
def foo(param=DEFAULT): 
    if param is DEFAULT: 
     ... 

आमतौर पर आप सिर्फ None डिफ़ॉल्ट मान के रूप में उपयोग कर सकते हैं, अगर यह एक मूल्य के उपयोगकर्ता पारित करने के लिए चाहते हो जाएगा के रूप में मतलब नहीं है।

विकल्प kwargs उपयोग करने के लिए है:

def foo(**kwargs): 
    if 'param' in kwargs: 
     param = kwargs['param'] 
    else: 
     ... 

हालांकि इस overly वर्बोज़ है और उपयोग करने के लिए के रूप में अपनी प्रलेखन स्वचालित रूप से param पैरामीटर शामिल नहीं होगा अपने कार्य और अधिक कठिन बना देता है।

+0

धन्यवाद, मुझे लगता है कि मैं किसी भी – Matthias

+4

के लिए चेक पर टिकेगा, मैंने देखा है कि कई लोग उन जगहों के लिए इलिप्सिस बिल्टिन का उपयोग करते हैं जहां इसकी आवश्यकता है और कोई भी वैध इनपुट नहीं माना जाता है। यह अनिवार्य रूप से पहले उदाहरण के समान ही है। – GrandOpener

2

मैं अस्थिरता की टिप्पणी से सहमत हूं।

def function(arg1,...,**optional): 
    if 'optional_arg' in optional: 
     # user has set 'optional_arg' 
    else: 
     # user has not set 'optional_arg' 
     optional['optional_arg'] = optional_arg_default_value # set default 
+0

मेरा मानना ​​है कि एक वैकल्पिक पैरामीटर कुछ है जैसे 'def func (वैकल्पिक = मान) '' 'kwargs' –

+0

ऐसा कुछ है जो व्याख्या के लिए कुछ हद तक खुला है। डिफ़ॉल्ट मान और कीवर्ड तर्क के साथ तर्क के बीच वास्तविक अंतर क्या है? वे दोनों एक ही वाक्यविन्यास "कीवर्ड = मान" का उपयोग करके व्यक्त किए जाते हैं। – isedev

+0

मैं असहमत हूं, क्योंकि वैकल्पिक पैरामीटर और '** kwargs' का उद्देश्य थोड़ा अलग है। अनुलेख कोई समस्या नहीं है -1 :) और मेरे लिए आपके -1 आकस्मिक थे :) –

0

एक छोटी सी अजीब दृष्टिकोण होगा:

कौन सा आउटपुट: लेकिन आप निम्नलिखित तरीके से जांच कर सकता है

passed default 
z 
passed different 
b 
not passed 
z 

अब इस, जैसा कि मैंने उल्लेख किया है, काफी अजीब है , लेकिन यह नौकरी करता है। हालांकि यह काफी पढ़ा जा सकता है और इसी तरह ecatmur के suggestion को स्वचालित रूप से प्रलेखित नहीं किया जाएगा।

+1

आप 'check_f (' z ')' का व्यवहार शामिल करना चाहेंगे, जैसा कि आप कहते हैं, अजीब। –

+0

@ माइकल जे। बार्बर गुड प्वाइंट। आपको * तर्कों के साथ कुछ "जादू" करना होगा। हालांकि, मेरा मुद्दा यह था कि यह संभव है, लेकिन अब यह आवश्यक है कि डिफ़ॉल्ट मान पास हो या नहीं, एक खराब डिज़ाइन है। – dmg

7

निम्नलिखित फ़ंक्शन सजावट, explicit_checker, स्पष्ट रूप से दिए गए सभी पैरामीटर के पैरामीटर नामों का एक सेट बनाता है। यह परिणाम को अतिरिक्त पैरामीटर (explicit_params) फ़ंक्शन में जोड़ता है। पैरामीटर a को स्पष्ट रूप से दिया गया है या नहीं, यह जांचने के लिए बस 'a' in explicit_params करें।

def explicit_checker(f): 
    varnames = f.func_code.co_varnames 
    def wrapper(*a, **kw): 
     kw['explicit_params'] = set(list(varnames[:len(a)]) + kw.keys()) 
     return f(*a, **kw) 
    return wrapper 

@explicit_checker 
def my_function(a, b=0, c=1, explicit_params=None): 
    print a, b, c, explicit_params 
    if 'b' in explicit_params: 
     pass # Do whatever you want 


my_function(1) 
my_function(1, 0) 
my_function(1, c=1) 
4

मैं कभी-कभी सार्वभौमिक अद्वितीय स्ट्रिंग (यूयूआईडी की तरह) का उपयोग करता हूं।

import uuid 
DEFAULT = uuid.uuid4() 
def foo(arg=DEFAULT): 
    if arg is DEFAULT: 
    # it was not passed in 
    else: 
    # it was passed in 

इस तरह, कोई उपयोगकर्ता भी डिफ़ॉल्ट लगता है कि हो सकता है अगर वे तो मैं पूरी तरह आश्वस्त हो कि जब मैं arg के लिए है कि मूल्य देखते हैं, उस में पारित नहीं किया गया था हो सकता है की कोशिश की।

+0

यह एक हैक का थोड़ा सा है, लेकिन संक्षेप में और प्रभावी ... – F1Rumors

+0

पायथन ऑब्जेक्ट संदर्भ हैं, आप केवल 'uuid4()' के बजाय 'ऑब्जेक्ट() 'का उपयोग कर सकते हैं - यह अभी भी एक अद्वितीय _instance_ है, जो कि' है ' चेकों –

0

मैं इस देखा है पैटर्न कई बार (जैसे पुस्तकालय unittest, py-flags, jinja):

class Default: 
    def __repr__(self): 
     return "DEFAULT" 

DEFAULT = Default() 

... या समकक्ष एक लाइनर ...:

DEFAULT = type('Default',(), { '__repr__': lambda x: 'DEFAULT' })() 

DEFAULT = object() के विपरीत, इस टाइप-चेकिंग सहायता करता है और जानकारी जब त्रुटियां होती हैं प्रदान करता है - अक्सर या तो स्ट्रिंग प्रतिनिधित्व ("DEFAULT") या वर्ग के नाम ("Default") त्रुटि संदेश में किया जाता है।