2015-02-23 18 views
5

का उपयोग करके अजगर में जिम्मेदारी पैटर्न की श्रृंखला लागू करना मैं पाइथन में विभिन्न अवधारणाओं की खोज कर रहा हूं और मुझे कोरआउटिन के उदाहरण पर पढ़ना पड़ा जिसका उपयोग जिम्मेदारी डिजाइन पैटर्न की श्रृंखला के लिए किया जा सकता है।कोरआउट

from functools import wraps 

def coroutine(function): 
    @wraps(function) 
    def wrapper(*args, **kwargs): 
     generator = function(*args, **kwargs) 
     next(generator) 
     return generator 
    return wrapper 

@coroutine 
def PlatinumCustomer(successor=None): 
    cust = (yield) 
    if cust.custtype == 'platinum': 
     print "Platinum Customer" 
    elif successor is not None: 
     successor.send(cust) 

@coroutine 
def GoldCustomer(successor=None): 
    cust = (yield) 
    if cust.custtype == 'gold': 
     print "Gold Customer" 
    elif successor is not None: 
     successor.send(cust) 

@coroutine 
def SilverCustomer(successor=None): 
    cust = (yield) 
    if cust.custtype == 'silver': 
     print "Silver Customer" 
    elif successor is not None: 
     successor.send(cust) 

@coroutine 
def DiamondCustomer(successor=None): 
    cust = (yield) 
    if cust.custtype == 'diamond': 
     print "Diamond Customer" 
    elif successor is not None: 
     successor.send(cust) 

class Customer: 
    pipeline = PlatinumCustomer(GoldCustomer(SilverCustomer(DiamondCustomer()))) 

    def __init__(self,custtype): 
     self.custtype = custtype 

    def HandleCustomer(self): 
     try: 
      self.pipeline.send(self) 
     except StopIteration: 
      pass 

if __name__ == '__main__': 
    platinum = Customer('platinum') 
    gold = Customer('gold') 
    silver = Customer('silver') 
    diamond = Customer('diamond') 
    undefined = Customer('undefined') 

    platinum.HandleCustomer() 
    gold.HandleCustomer() 
    undefined.HandleCustomer() 

क्या मैं यहाँ करने के लिए कोशिश की है ग्राहकों (प्लेटिनम, सोना, हीरा, रजत) के विभिन्न प्रकार से निपटने के लिए जिम्मेदारी पैटर्न समाधान की एक श्रृंखला बनाने का प्रयास है: मैं निम्नलिखित कोड लिखा था।

उस ग्राहक के पास एक पाइपलाइन है जहां मैंने उस आदेश का उल्लेख किया है जिसमें विभिन्न ग्राहकों को संभाला जाएगा। ग्राहक() हैंडल कस्टमर पाइपलाइन के माध्यम से खुद का एक उदाहरण भेजेगा जो जांच करेगा कि उसके कस्टमाइप से मेल खाता है या फिर उसे इसके उत्तराधिकारी (यदि उपलब्ध हो)

समस्या: समस्या यह है कि मैं उपर्युक्त स्क्रिप्ट चलाता हूं, यह पहले प्लैटिनम ग्राहक को संभालेगा लेकिन सोने या अपरिभाषित नहीं होगा। मुझे लगता है कि ऐसा इसलिए है क्योंकि वह जनरेटर के अंत तक पहुंच गया है। मैं कोड को कैसे संशोधित करूं ताकि प्रत्येक बार जब यह ग्राहक का एक नया उदाहरण हो, तो यह इसकी शुरुआत से पाइपलाइन के माध्यम से जाएगा?

उत्तर

4

आपका coroutines पाश चाहिए हमेशा के क्रम में के रूप में, लगातार कॉल संभाल करने में:

@coroutine 
def PlatinumCustomer(successor=None): 
    while 1: # <---- this is missing from your coroutines 
     cust = (yield) 
     if cust.custtype == 'platinum': 
      print "Platinum Customer" 
     elif successor is not None: 
      successor.send(cust) 

और 'अनिर्धारित' प्रकार संभाल करने के लिए, आप एक अंतिम कैच-ऑल हैंडलर की आवश्यकता होगी:

@coroutine 
def UndefinedCustomer(): 
    while 1: 
     cust = (yield) 
     print "No such customer type '%s'" % cust.custtype 

और अपने पाइप लाइन में जोड़ें:

pipeline = PlatinumCustomer(GoldCustomer(SilverCustomer(DiamondCustomer(UndefinedCustomer())))) 

(एक समाप्त UndefinedCustomer हैंडलर भी आप की अनुमति देगा अपने कोरआउट से 'अगर कोई उत्तराधिकारी नहीं है' कोड को हटाने के लिए - सभी को टर्मिनेटर को छोड़कर उत्तराधिकारी होंगे, जो जानता है कि यह टर्मिनेटर है और उत्तराधिकारी को कॉल नहीं करेगा।)

इन परिवर्तनों के साथ, मुझे यह मिलता है आपके परीक्षणों से आउटपुट:

Platinum Customer 
Gold Customer 
No such customer type 'undefined' 

इसके अलावा, हैंडल कस्टमर में स्टॉपइटरेशन के लिए कैच क्यों? यह कोड पर्याप्त होना चाहिए:

def HandleCustomer(self): 
    self.pipeline.send(self) 
+0

एक आकर्षण की तरह काम करता है। – Rivas

+0

अपवर्तित करने में सक्षम नहीं होने के लिए मैं क्षमा चाहता हूं। मेरे पास पर्याप्त प्रतिष्ठा नहीं है। – Rivas

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