2010-10-29 18 views
6

मेरे पास एक ऐसा फ़ंक्शन है जहां मुझे किसी अन्य प्रोग्राम के लिए अलग-अलग आउटपुट स्ट्रिंग जेनरेट करने की आवश्यकता होती है, जिस पर वह चाहता है।पायथन में विभिन्न प्रकारों को संभालने का कैननिक तरीका क्या है?

असल में, कॉल किए गए प्रोग्राम को कमांड लाइन तर्क की आवश्यकता होती है जो इसे बताती है कि इसे किस प्रकार कहा जाता है।

खुशी से मुझे this answer पर प्रकार के लिए एक चर की जांच करने के लिए मिला। लेकिन मैंने देखा कि लोगों ने आपत्तियों को कैसे उठाया, कि प्रकारों की जांच करने से "ऑब्जेक्ट ओरिएंटेड" डिज़ाइन नहीं होता है। तो, क्या कोई अन्य तरीका है, बिना किसी प्रकार की जांच किए बिना इसे संभालने का अधिक "अधिक ऑब्जेक्ट उन्मुख" तरीका संभव है?

कोड मेरे पास अब कुछ इस तरह चला जाता है:

def myfunc(val): 
    cmd_type = 'i' 
    if instance(val, str): 
     cmd_type = 's' 

    cmdline = 'magicprogram ' + cmd_type + ' ' + val 
    Popen(cmdline, ... blah blah) 
    ... 

जो सिर्फ ठीक काम करता है, लेकिन मैं सिर्फ अगर वहाँ कुछ तकनीक मैं से अनजान हूँ जानना चाहता था।

+0

आप कमांड लाइन पर किसी प्रकार के साथ कुछ भी कैसे पारित कर रहे हैं? – geoffspear

+0

@Wobble, मैंने एक उदाहरण जोड़ा। मुझे एहसास हुआ कि सवाल बहुत स्पष्ट नहीं था। उम्मीद है कि यह अब बेहतर है। –

+0

myfunc कैसे कहा जाता है? मैं सुझाव दूंगा कि दो अलग-अलग फ़ंक्शन हैं जो एक अलग प्रकार के तर्क की अपेक्षा करते हैं, फिर फ़ंक्शन के निचले भाग का एक निजी फ़ंक्शन बनाएं जिसे आप प्रत्येक पूर्व कार्यों से उचित तर्क के साथ बुलाते हैं। – teukkam

उत्तर

3

मुझे नहीं लगता कि डबल भेजने या मुल्टीमेथड्स विशेष रूप से प्रासंगिक है और न ही आपत्ति लोगों की है कि अन्य पड़ा तो जवाब के साथ क्या करना ज्यादा की क्या ज़रूरत है।

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

class Value(object): 
    """ Generic container of values. """ 
    def __init__(self, type_, val): 
     self.type = type_ # using 'type_' to avoid hiding built-in 
     self.val = val 

def myfunc(val): 
    # Look ma, no type-checking! 
    cmdline = 'magicprogram {obj.type} {obj.val}'.format(obj=val) 
    print 'Popen({!r}, ... blah blah)'.format(cmdline) 
    # ... 

val1 = Value('i', 42) 
val2 = Value('s', 'foobar') 

myfunc(val1) # Popen('magicprogram i 42', ... blah blah) 
myfunc(val2) # Popen('magicprogram s foobar', ... blah blah) 

यह और भी वस्तु उन्मुख हो सकता है अगर वहाँ परोक्ष रूप से उसके गुण का उपयोग करने के Value कक्षा में तरीकों थे, लेकिन सिर्फ कर उपरोक्त कुख्यात प्रकार की जांच से छुटकारा पाता है। अधिक ऑब्जेक्ट उन्मुख डिज़ाइन के पास प्रत्येक प्रकार के Value के लिए एक अलग सबक्लास होगा, जो सभी myfunc() जैसे ग्राहकों के लिए विधियों का एक सामान्य सेट साझा करते हैं, ताकि उन्हें जानकारी बनाने, कुशल बनाने और निकालने के लिए उपयोग किया जा सके।

ऑब्जेक्ट्स का उपयोग करने का एक अन्य लाभ यह है कि आपको myfunc() को संशोधित नहीं करना चाहिए यदि आप अपने आवेदन के नए प्रकार के 'वैल्यू' के लिए समर्थन जोड़ते हैं - यदि "वैल्यू" के सार का आपका अमूर्तता है एक अच्छा, वह है।

5

आप Double Dispatch या Multimethods का उपयोग कर सकते हैं।

+1

और पायथन में, यह http://www.artima.com/weblogs/viewpost.jsp?thread=101605 और http://en.wikipedia.org/wiki/Multiple_dispatch#Python मुझे लगता है। धन्यवाद! –

+0

मेरे उद्देश्यों के लिए, मुझे लगता है कि मैं इस प्रकार की जांच करने के लिए चिपक जाऊंगा, लेकिन यह एक बहुत ही प्रबुद्ध अनुभव था, दोनों पाइथन कैसे काम करता है और लोग इन मुद्दों के बारे में कैसे सोचते हैं। अपने उत्तर को स्वीकार करते हुए यह मेरे प्रश्न का सबसे करीबी उत्तर देता है क्योंकि इसे तैयार किया गया था। –

1

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

संपादित करें:

Val = "a string" 
myfunc = myfuncStringVersion 

और अधिक या कम एक वर्ग केवल एक मूल्य और समारोह में विभाजित में वैल लपेटकर के साथ एक ही बात क्या तुम करोगी कर की तर्ज पर पिछले संस्करण कुछ समझाने के लिए जब से तुम नहीं हो सकता है एक कक्षा में वैल लपेटना चाहते हैं।

+0

"आप एक चर के लिए एक विशिष्ट विशिष्ट मावल फ़ंक्शन भी असाइन कर सकते हैं, तब कॉल करें जब आपको आवश्यकता हो।" <---- मैंने इसे बार-बार पढ़ा, मुझे यह नहीं मिला। –

+0

@Amigable क्लार्क कांट क्षमा करें कि उम्मीद है कि यह अब और अधिक समझ में आता है। – stonemetal

3
But I noticed how people also raised objections, 
that checking for types betrays a "not object oriented" design 

वास्तव में यह Duck typing style कहा जाता है ("यह एक बतख की तरह लग रहा है और एक बतख की तरह नीम हकीमों है, यह एक बतख होना चाहिए।"), और यह अजगर भाषा है कि प्रोग्रामिंग की इस शैली का उपयोग करना चाहिये है।

def myfunc(val): 
    cmd_type = 'i' 

    # forget about passing type to your magicprogram 
    cmdline = 'magicprogram %s ' % val 
    Popen(cmdline, ... blah blah) 
:

और बतख टाइपिंग के साथ आए कुछ कॉल EAFP (आसान अनुमति से माफी पूछो करने के लिए)

presumable more "more object oriented" way of handling this without 
    explicitly checking for type? 

आप अधिक pythonic मतलब है, मूल रूप से क्या अपने मामले में और अधिक pythonic हो जाएगा कुछ इस तरह है

और अपने magicprogram में (मैं अगर यह अपनी स्क्रिप्ट या ... है पता नहीं है), और क्योंकि सभी मामलों में अपने कार्यक्रम के एक स्ट्रिंग मिल जाएगा तो बस यह जो भी आपके स्क्रिप्ट accep को बदलने की कोशिश टी;

from optparse import OptionParser 

# .... 

if __name__ == '__main__': 

    parser = OptionParser(usage="blah blah") 

    # ... 
    (options, args) = parser.parse_args() 

    # Here you apply the EAFP with all type accepted. 
    try: 
     # call the function that will deal with if arg is string 
     # remember duck typing. 
    except ... : 
     # You can continue here 

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

आशा है कि यह आपके लिए चीजों को साफ़ करेगा।

+0

ठीक है, मेरे मामले में जादूप्रवाह एनईटी-एसएनएमपी है, और इसे बदलना एक विकल्प नहीं है। लेकिन वैसे भी विचारों के लिए धन्यवाद। –

+0

आह ठीक है, लेकिन मुझे उम्मीद है कि मेरे उत्तर में अजगर दर्शन के बारे में स्पष्ट चीजें हैं; बतख टाइपिंग और ईएएफपी :) – mouad

+0

"इसमें डक टाइपिंग शैली करने के लिए कुछ है, और यह पाइथन दर्शन है और ऑब्जेक्ट उन्मुख नहीं है" सत्य नहीं है और डक्ट टाइपिंग की आवश्यकता नहीं है। यह किसी भी भाषा के लिए सच है जो [polymorphism] का समर्थन करता है (http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming) और कई (अधिकांश?) ओओ लोग करते हैं, मुझे विश्वास है। – martineau

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

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