2012-05-04 17 views
5

मैं एक इवेंट डिस्पैचर फ्रेमवर्क बना रहा हूं जो संदेशों को डीकोड करता है और उपयोगकर्ता कोड में वापस कॉल करता है। मेरे सी ++ पृष्ठभूमि पता चलता है कि मैं लिखने:क्या यह इडियोटिक पाइथन घटना हैंडलर कॉलबैक के लिए एक अमूर्त वर्ग का उपयोग करने के लिए है?

class Handler: 
    def onFoo(self): 
     pass 
    def onBar(self): 
     pass 

class Dispatcher: 
    def __init__(self): 
     self.handler = Handler() 

    def run(): 
     while True: 
      msg = decode_message() # magic 
      if msg == 'foo': 
       handler.onFoo() 
      if msg == 'bar': 
       handler.onBar() 

तब ढांचे उपयोगकर्ता की तरह कुछ लिखते थे:

class MyHandler(Handler): 
    def onFoo(self): 
     do_something() 

dispatcher = Dispatcher() 
myHandler = MyHandler() 
dispatcher.handler = myHandler 
dispatcher.run() 

लेकिन मैं यह भी onFoo() और onBar()Dispatcher के तरीके के रूप में डाल और उपयोगकर्ता उन्हें बदलने के कल्पना कर सकते हैं अन्य तरीकों के साथ। फिर उपयोगकर्ता का कोड लगेगा जैसे:

def onFoo(): 
    do_something() 

dispatcher = Dispatcher() 
dispatcher.onFoo = onFoo 

मैं भी Dispatcher.onFoo callables की एक सूची बना सकते हैं, तो उपयोगकर्ता सी # में की तरह एक से अधिक हैंडलर देते हैं सकता है।

ऐसा करने का सबसे पाइथोनिक तरीका क्या है?

+0

आप इवेंट डिस्पैचर फ्रेमवर्क क्यों बना रहे हैं? बहुत पहले से मौजूद हैं। – Marcin

+0

मैं कुछ भी सामान्य उद्देश्य नहीं बना रहा हूं - मैंने शायद परियोजना को वास्तव में उससे बड़ा ध्वनि बनाया है। यह सिर्फ एक मैसेजिंग परत है जो प्रोटोकॉल बफर संदेशों को डीकोड करता है और उपयुक्त कार्यों को कॉल करता है। – japreiss

+0

थोड़ा और विस्तार करने के लिए: मैं तीसरे पक्ष के पुस्तकालयों पर बहुत अधिक भरोसा करना टालना चाहता हूं क्योंकि मुझे पहले से ही मेरी कंपनी के बड़े स्वामित्व कोड बेस में उन्हें कुछ दर्द का सामना करना पड़ा है। मैं पुस्तकालयों को झुकाव और इनवेंटेड कोड के साथ बदलने की संभावना रखना चाहता हूं। – japreiss

उत्तर

4

मैं नहीं कह सकते हैं कि वहाँ कुछ भी विशेष रूप से गलत है कि यह पहली बार जिस तरह से करने के बारे में, खासकर यदि आप Dispatcher उद्देश्यों को रन टाइम पर एक संगठित तरीके में अनुकूलित किया जा करने के लिए अनुमति देना चाहते हैं (करने के लिए Handler वस्तुओं के विभिन्न प्रकार गुजर द्वारा अर्थात् उन्हें), यदि आपके Handler को जटिल स्थिति के साथ बातचीत करने और बनाए रखने की आवश्यकता है।

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

किसी भी मामले में, मैं व्यक्तिगत रूप से आपके द्वारा सुझाए गए दूसरे स्थान पर पहला दृष्टिकोण पसंद करूंगा; मुझे यकीन नहीं है कि या तो "पायथनिक" है, लेकिन पहला मुझे क्लीनर दृष्टिकोण की तरह लगता है, क्योंकि यह Handler और Dispatcher तर्क अलग रखता है। (यह एक आप threading.Thread में देखते हैं जहाँ आप केवल सुरक्षित रूप से कुछ तरीकों ओवरराइड कर सकते हैं इस तरह की स्थितियों से बचा जाता है -। मैं हमेशा पाया है कि एक सा कर्कश)

मैं मैं बाहर बिंदु चाहिए, हालांकि, कि अगर आप वास्तव में एक वास्तविक सार आधार वर्ग चाहते हैं, आपको एक लिखना चाहिए! 2.6 के रूप में, पायथन लचीला abstract base classes के लिए बहुत अच्छी कार्यक्षमता के साथ समर्थन प्रदान करता है। उदाहरण के लिए, आप abstractmethod सजावट के साथ एक अमूर्त विधि को परिभाषित कर सकते हैं, जो सुनिश्चित करता है कि उपclass द्वारा ओवरराइड किया जाना चाहिए; लेकिन आप उन नियमित तरीकों को भी परिभाषित कर सकते हैं जिन्हें ओवरराइड नहीं किया जाना चाहिए। यदि आप सी ++ मुहावरे के पाइथोनिक संस्करण की तलाश में हैं, तो शायद यह जाने का सबसे अच्छा तरीका है - यह वही बात नहीं है, लेकिन यह आपके पास अब जो कुछ है उसके करीब आता है।

+0

मुझे अमूर्त आधार वर्गों की बहुत परवाह नहीं है। मैं एक डिफ़ॉल्ट नो-ऑप व्यवहार प्रदान करना चाहता हूं ताकि उपयोगकर्ताओं को हर घटना को संभालने की आवश्यकता न हो, यदि वे नहीं चाहते हैं। – japreiss

+0

@japreiss, आह, मैं देखता हूं - यह समझ में आता है। मैं इस तरह से इस बारे में सोच नहीं रहा था। मुझे यकीन नहीं है कि _pythonicity_ तब इसमें आता है; इसके लायक होने के लिए, मैं पहला संस्करण पसंद करूंगा, लेकिन मुझे नहीं लगता कि या तो दूसरे की तुलना में अधिक पाइथनिक है। – senderle

+0

क्या ऐसा करने का कोई बेहतर तरीका है? ऐसा लगता है कि ईवेंट हैंडलर के लिए ट्विस्टेड क्लास विरासत का उपयोग करता है। मैंने पायथन में बहुत अधिक घटना संचालित चीजें नहीं की हैं, इसलिए मुझे यकीन नहीं है कि यह 'सामान्य' तरीका है या नहीं। – japreiss