2011-08-12 14 views
7

लंबे समय तक मैं यह पता लगाने की कोशिश कर रहा हूं कि पाइथन कार्यों में झंडे को पार करने का सबसे अच्छा तरीका क्या है। सबसे सरल तरीका है कुछ की तरह:पायथन: फ़ंक्शन को फ़्लैग पास करना

def func(data, flag1, flag2, flag3): 
    ... 

func(my_data, True, False, True) 

के बाद से शब्द "सही" या "गलत" आप क्या ध्वज सेट किया जा रहा है के बारे में कुछ भी नहीं बताता है यह, वास्तव में अच्छा और संक्षिप्त है, लेकिन अविश्वसनीय रूप से पढ़ने के लिए मुश्किल है, और आप बाईं ओर से शुरू होने वाले तर्कों को ध्यान से गिनना होगा। आप उन्हें कीवर्ड तर्क कर सकते हैं:

def func(data, flag1=False, flag2=False, flag3=False): 
    ... 

func(my_data, flag1=True, flag3=True) 

लेकिन इस तरह के अनावश्यक है, क्योंकि "सही" कोई अर्थ बिल्कुल नहीं होता। मैं इसे एक सूची के रूप गुजारें सकता:

func(mydata, ['flag1', 'flag3']) 

या

func(mydata, [func.flag1, func.flag3]) 

लेकिन पहले नहीं बल्कि गंदा लगता है, झंडे के रूप में तार का उपयोग कर, और दूसरा अभी भी कुछ हद तक दोहराव है। आदर्श रूप में मैं कुछ कहना चाहता हूं:

func(my_data, flag1, flag3) 

न्यूनतम क्रियाशक्ति और अनावश्यकता के साथ एक समारोह में झंडे को पारित करने के लिए। क्या अजगर में ऐसा कुछ करने का कोई तरीका है?

संपादित करें: मैं के साथ जा रहा समाप्त हो गया: संकलन समय (तार गुजर रहा बनाम) की जाँच, कोई नाम स्थान प्रदूषण (के रूप में वैश्विक "enum" s का उपयोग करके करने का विरोध किया:

func(mydata, flagA=1, flagB=1) 
ज्यादातर वर्णित कारणों के लिए

) और न्यूनतम बॉयलरप्लेट (= 1 या = 0 केवल 2 अक्षर हैं, बनाम 5 या 6 = सही या = गलत)। यह भी बहुत आसान झंडे के लिए डिफ़ॉल्ट मान सेट करता है:

def func(data, flagA=1, flagB=0, flagC=1): 
    ... 

जो कहीं अधिक स्पष्ट और हुप्स के माध्यम से कूद करने के लिए निकालने और ** kwarg शैली झंडे चूक आवंटित करने के लिए तुलना में कहीं अधिक आसान है। झंडे मूल रूप से स्थाई रूप से चेक किए जाते हैं और लिखने के लिए बहुत स्पष्ट/साफ होते हैं। अब अगर केवल मैं पिछले दो पात्रों ...

+1

आप/पहली जगह में झंडे उत्तीर्ण करने की आवश्यकता क्यों करना चाहते हैं? शायद आपको अपने इंटरफ़ेस पर पुनर्विचार करना चाहिए ... –

+0

झंडे का उपयोग डेटा संरचना में बूल सेट करने के लिए किया जाएगा, जो तब डेटा संरचना पर चलने वाले कार्यों के भविष्य के व्यवहार को नियंत्रित करेगा। यह एक पूरी तरह गैर-ओओ दृष्टिकोण है, लेकिन मैंने इसे सादगी से चुना है; भले ही, मैंने इसे ओओ-स्टाइल किया है, व्यवहारिक परिवर्तन बहुत सूक्ष्म हैं और शायद कक्षाओं के पूरे परिवार को संभालने के लायक नहीं हैं। –

+0

हो सकता है कि आप मूल्यों वाले एक (सरल) डेटा संरचना को पास कर सकें? झंडे का एक 'सेट', या 'dict' मैपिंग ध्वज नाम बूल के लिए ... –

उत्तर

3

कुछ अजगर मानक पुस्तकालयों इस का उपयोग करें:

re.match(pattern, str, re.MULTILINE | re.IGNORECASE) 

आप * args का उपयोग करके इस दृष्टिकोण में बदलाव कर सकते हैं:

    :

    my.func(a, b, c, my.MULTLINE, my.IGNORECASE) 
    

    मैं वास्तव में flag1 = सच के साथ जा रहा सिफारिश करेंगे

  • यह पठनीय
  • ध्वज नाम संकलित पर चेक किया गया है समय (जब तक ** kwargs प्रयोग किया जाता है)
  • आप लंबे नाम पुन: लिखने के बिना यह सच है और झूठे के बजाय झंडा = 1 और ध्वज = 0 का उपयोग कर सकते
  • आप अस्थायी रूप से बदल सकते हैं LONG_FLAG_NAME_YOU_DONT_REMEMBER = गलत पर यह सच है शोर को कम करने के लिए जब आप
3
* args के साथ

बंद दाढ़ी सकता है:

def some_func(data, *args): 
    # do something 
    return args # this is just to show how it works 


>>> print some_func(12, 'test', 'test2', 'test3') 
('test', 'test2', 'test3') 

यह समझने के लिए * args और ** kwargs काम एक अच्छा सवाल है: *args and **kwargs?

5

आप flag1 ... flagN वैश्विक चर के रूप में परिभाषित कर सकते हैं, और func(*args)

FLAG1 = 1 
FLAG2 = 2 

def func(*args): 
    pass 

func(FLAG1, FLAG2) 

तक परिभाषा के साथ अपने समारोह को परिभाषित एनजी फ्लैग अलग-अलग, स्ट्रिंग का उपयोग करने के बजाय, आप फ्लैग के नामों में टाइपो से बच सकते हैं और कुछ सिरदर्द

-1

मैं झंडे के बिना फ़ंक्शन पसंद करता हूं। इसके बजाय:

def func_flag1(arg): 
    pass # something useful 

def func_flag2(arg): 
    pass # something for flag 2. 

लेकिन "फ्लैगएक्स" वास्तव में "do_X_with_option" जैसा सार्थक होगा।

मैं इसे पसंद करता हूं क्योंकि यह इसे स्पष्ट बनाता है, आप कार्यों को सरल (कम बग) रखते हैं, और आपको कुछ स्थिरांक को अन्य मॉड्यूल में ले जाने की आवश्यकता नहीं है (झंडे के मामले में वास्तव में कुछ प्रकार की गणना होती है)।

+0

समस्या यह है कि मेरे झंडे बहुत ही स्वतंत्र हैं; इस प्रकार ओ (एन) झंडे क्या ले जाएगा ओ (2^एन) कार्यों को अनुकरण करने के लिए ले जाएगा। मेरे पास अभी 2 झंडे हैं, जो 4 कार्य करेंगे, और यह 3 या 4 झंडे –

3

इसे बदलने के बारे में क्या होगा?

flag1, flag2, flag3, flag4, flag5, flag6 = range(6) 

def func(enable=[], disable=[], 
     enabled_by_default=[flag5, flag6]): 
    enabled = set(enabled_by_default + enabled) - set(disabled) 
    if flag1 in enabled: 
     ... 
    if flag2 in enabled: 
     ... 

func(enable = [flag1, flag2, flag3], 
    disable = [flag6]) 
3

मैं अच्छे पुराने bitwise झंडे याद आ रही है:

a = 1 
b = 2 
c = 4 
d = 8 

def func(data, flags): 
    print((flags & a) == a) 
    print((flags & b) == b) 
    print((flags & c) == c) 
    print((flags & d) == d) 

>>>> func("bla", a|c|d) 
>>>> True 
>>>> False 
>>>> True 
>>>> True 
+0

के लिए जल्दी से हाथ से बाहर निकल जाएगा इसे दिखाने के लिए धन्यवाद। मैंने "पायथन बिट झंडे" पर आधे घंटे के लिए Google की खोज की। – Arne

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