पायथन डिज़ाइन पैटर्न - त्वरित गाइड
सॉफ़्टवेयर या वेब एप्लिकेशन बनाने के लिए डेवलपर्स द्वारा उपयोग किए जाने वाले पैटर्न का प्रतिनिधित्व करने के लिए डिज़ाइन पैटर्न का उपयोग किया जाता है। ये पैटर्न आवश्यकता विश्लेषण के आधार पर चुने गए हैं। पैटर्न समस्या के समाधान का वर्णन करता है, जब और जहां समाधान लागू करने के लिए और जहां कार्यान्वयन के परिणाम।
एक डिजाइन पैटर्न की संरचना
डिजाइन पैटर्न का प्रलेखन एक तरह से बनाए रखा जाता है जो उपयोग की जाने वाली तकनीक पर और किन तरीकों पर अधिक ध्यान केंद्रित करता है। निम्नलिखित आरेख डिजाइन पैटर्न प्रलेखन की मूल संरचना की व्याख्या करता है।
पैटर्न का नाम
यह लघु और प्रभावी तरीके से पैटर्न का वर्णन करता है।
आशय / मकसद
यह वर्णन करता है कि पैटर्न क्या करता है।
प्रयोज्यता
यह उन स्थितियों की सूची का वर्णन करता है जहां पैटर्न लागू है।
प्रतिभागियों और परिणाम
प्रतिभागियों में वर्ग और ऑब्जेक्ट शामिल होते हैं जो पैटर्न के साथ मौजूद परिणामों की सूची के साथ डिजाइन पैटर्न में भाग लेते हैं।
क्यों अजगर?
पायथन एक ओपन सोर्स स्क्रिप्टिंग भाषा है। इसमें पुस्तकालय हैं जो विभिन्न प्रकार के डिजाइन पैटर्न का समर्थन करते हैं। अजगर के वाक्यविन्यास को समझना आसान है और अंग्रेजी कीवर्ड का उपयोग करता है।
पायथन नीचे दिए गए डिज़ाइन पैटर्न की सूची के लिए समर्थन प्रदान करता है। इन डिज़ाइन पैटर्न का उपयोग इस पूरे ट्यूटोरियल में किया जाएगा -
- मॉडल व्यू कंट्रोलर पैटर्न
- सिंगलटन पैटर्न
- फैक्टरी पैटर्न
- बिल्डर पैटर्न
- प्रोटोटाइप पैटर्न
- मुखौटा पैटर्न
- कमांड पैटर्न
- एडाप्टर पैटर्न
- प्रोटोटाइप पैटर्न
- डेकोरेटर पैटर्न
- प्रॉक्सी पैटर्न
- जिम्मेदारी पैटर्न की श्रृंखला
- ऑब्जर्वर पैटर्न
- स्टेट पैटर्न
- रणनीति पैटर्न
- टेम्पलेट पैटर्न
- फ्लाईवेट पैटर्न
- सार फैक्टरी पैटर्न
- ऑब्जेक्ट ओरिएंटेड पैटर्न
डिजाइन पैटर्न का उपयोग करने के लाभ
डिज़ाइन पैटर्न के विभिन्न लाभ निम्नलिखित हैं -
पैटर्न डेवलपर को निर्दिष्ट समस्याओं के लिए कोशिश की और परीक्षण किए गए समाधानों का चयन प्रदान करते हैं।
सभी डिजाइन पैटर्न भाषा तटस्थ हैं।
पैटर्न संचार प्राप्त करने और अच्छी तरह से प्रलेखन बनाए रखने में मदद करते हैं।
इसमें परियोजना के लिए किसी भी तकनीकी जोखिम को कम करने के लिए उपलब्धि का रिकॉर्ड शामिल है।
उपयोग करने के लिए डिज़ाइन पैटर्न अत्यधिक लचीले होते हैं और समझने में आसान होते हैं।
पायथन एक ओपन सोर्स स्क्रिप्टिंग भाषा है, जो उच्च-स्तरीय, व्याख्यात्मक, इंटरैक्टिव और ऑब्जेक्ट-ओरिएंटेड है। इसे अत्यधिक पठनीय बनाया गया है। पायथन भाषा का वाक्यविन्यास अंग्रेजी कीवर्ड को समझने और उपयोग करने में आसान है।
पायथन भाषा की विशेषताएं
इस भाग में, हम पायथन भाषा की विभिन्न विशेषताओं के बारे में जानेंगे।
व्याख्या की
इंटरप्रेटर का उपयोग करके पायथन को रनटाइम पर संसाधित किया जाता है। निष्पादन से पहले कार्यक्रम को संकलित करने की आवश्यकता नहीं है। यह PERL और PHP के समान है।
वस्तु के उन्मुख
पायथन ऑब्जेक्ट-ओरिएंटेड स्टाइल और डिज़ाइन पैटर्न का अनुसरण करता है। इसमें विभिन्न परिभाषाओं जैसे कि एनकैप्सुलेशन, बहुरूपता और कई और अधिक के साथ वर्ग परिभाषा शामिल है।
पोर्टेबल
विंडोज ऑपरेटिंग सिस्टम में लिखा गया पायथन कोड और मैक ऑपरेटिंग सिस्टम में इस्तेमाल किया जा सकता है। आवश्यकताओं के अनुसार कोड का पुन: उपयोग और पोर्टेबल किया जा सकता है।
कोड करने के लिए आसान है
पायथन सिंटैक्स समझना और कोड करना आसान है। कोई भी डेवलपर कुछ घंटों के भीतर अजगर के वाक्य विन्यास को समझ सकता है। अजगर को "प्रोग्रामर-फ्रेंडली" के रूप में वर्णित किया जा सकता है
एक्सटेंसिबल
यदि आवश्यक हो, तो एक उपयोगकर्ता सी भाषा में कुछ पायथन कोड भी लिख सकता है। सी + + जैसी विभिन्न भाषाओं में स्रोत कोड में अजगर कोड डालना भी संभव है। यह पायथन को एक एक्स्टेंसिबल भाषा बनाता है।
महत्वपूर्ण बिंदु
पायथन प्रोग्रामिंग भाषा से संबंधित निम्नलिखित महत्वपूर्ण बिंदुओं पर विचार करें -
इसमें कार्यात्मक और संरचित प्रोग्रामिंग विधियों के साथ-साथ ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग विधियों को भी शामिल किया गया है।
इसका उपयोग स्क्रिप्टिंग भाषा के रूप में या प्रोग्रामिंग भाषा के रूप में किया जा सकता है।
इसमें स्वचालित कचरा संग्रह शामिल है।
इसमें उच्च-स्तरीय गतिशील डेटा प्रकार शामिल हैं और विभिन्न गतिशील प्रकार की जाँच का समर्थन करता है।
पायथन में C, C ++ और जावा जैसी भाषाओं के साथ एकीकरण की सुविधा शामिल है।
अपने सिस्टम में पायथन भाषा कैसे डाउनलोड करें?
अपने सिस्टम में पायथन भाषा डाउनलोड करने के लिए, इस लिंक का अनुसरण करें -
https://www.python.org/downloads/इसमें विंडोज, मैकओएस और लिनक्स वितरण जैसे विभिन्न ऑपरेटिंग सिस्टम के पैकेज शामिल हैं।
पायथन में महत्वपूर्ण उपकरण
इस खंड में, हम पायथन में कुछ महत्वपूर्ण उपकरणों के बारे में संक्षेप में जानेंगे।
पायथन स्ट्रिंग्स
स्ट्रिंग्स की मूल घोषणा इस प्रकार है -
str = 'Hello World!'
पायथन लिस्ट्स
अजगर की सूचियों को अल्पविराम द्वारा अलग किए गए यौगिक डेटा प्रकारों और चौकोर कोष्ठक ([]) के भीतर घोषित किया जा सकता है।
list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']
पायथन टुपल्स
टपल एक गतिशील डेटा प्रकार का पायथन है, जिसमें अल्पविराम द्वारा अलग किए गए मानों की संख्या होती है। टुपल्स कोष्ठक के साथ संलग्न हैं।
tinytuple = (123, 'john')
पायथन शब्दकोश
पायथन डिक्शनरी एक प्रकार की हैश टेबल है। एक शब्दकोश कुंजी पायथन के लगभग किसी भी डेटा प्रकार हो सकती है। डेटा प्रकार आमतौर पर संख्या या तार होते हैं।
tinydict = {'name': 'omkar','code':6734, 'dept': 'sales'}
पायथन में एक डिज़ाइन पैटर्न क्या है?
पायथन निम्नलिखित मापदंडों का उपयोग करके एक डिज़ाइन पैटर्न बनाने में मदद करता है -
- पैटर्न का नाम
- Intent
- Aliases
- Motivation
- Problem
- Solution
- Structure
- Participants
- Constraints
- नमूना कोड
मॉडल व्यू कंट्रोलर सबसे अधिक इस्तेमाल किया जाने वाला डिज़ाइन पैटर्न है। डेवलपर्स को इस डिज़ाइन पैटर्न को लागू करना आसान लगता है।
निम्नलिखित मॉडल व्यू कंट्रोलर की एक बुनियादी वास्तुकला है -
आइए अब देखते हैं कि संरचना कैसे काम करती है।
नमूना
इसमें शुद्ध एप्लिकेशन लॉजिक होता है, जो डेटाबेस के साथ इंटरैक्ट करता है। इसमें अंतिम उपयोगकर्ता के लिए डेटा का प्रतिनिधित्व करने के लिए सभी जानकारी शामिल है।
राय
देखें HTML फ़ाइलों का प्रतिनिधित्व करती है, जो अंत उपयोगकर्ता के साथ बातचीत करती हैं। यह उपयोगकर्ता को मॉडल के डेटा का प्रतिनिधित्व करता है।
नियंत्रक
यह दृश्य और मॉडल के बीच मध्यस्थ के रूप में कार्य करता है। यह उसी के लिए दृश्य और क्वेरीज़ मॉडल द्वारा ट्रिगर की गई घटनाओं को सुनता है।
पायथन कोड
आइए हम "व्यक्ति" नामक एक मूल वस्तु पर विचार करें और एक एमवीसी डिज़ाइन पैटर्न बनाएं।
Model.py
import json
class Person(object):
def __init__(self, first_name = None, last_name = None):
self.first_name = first_name
self.last_name = last_name
#returns Person name, ex: John Doe
def name(self):
return ("%s %s" % (self.first_name,self.last_name))
@classmethod
#returns all people inside db.txt as list of Person objects
def getAll(self):
database = open('db.txt', 'r')
result = []
json_list = json.loads(database.read())
for item in json_list:
item = json.loads(item)
person = Person(item['first_name'], item['last_name'])
result.append(person)
return result
यह एक विधि के लिए कहता है, जो डेटाबेस में व्यक्ति तालिका के सभी रिकॉर्ड प्राप्त करता है। रिकॉर्ड JSON प्रारूप में प्रस्तुत किए जाते हैं।
राय
यह मॉडल के भीतर प्राप्त सभी रिकॉर्ड प्रदर्शित करता है। कभी भी मॉडल के साथ बातचीत न करें; नियंत्रक यह काम करता है (मॉडल और दृश्य के साथ संचार)।
from model import Person
def showAllView(list):
print 'In our db we have %i users. Here they are:' % len(list)
for item in list:
print item.name()
def startView():
print 'MVC - the simplest example'
print 'Do you want to see everyone in my db?[y/n]'
def endView():
print 'Goodbye!'
नियंत्रक
नियंत्रक मॉडल के माध्यम से बातचीत करता है getAll() विधि जो अंतिम उपयोगकर्ता के लिए प्रदर्शित सभी रिकॉर्ड प्राप्त करती है।
from model import Person
import view
def showAll():
#gets list of all Person objects
people_in_db = Person.getAll()
#calls view
return view.showAllView(people_in_db)
def start():
view.startView()
input = raw_input()
if input == 'y':
return showAll()
else:
return view.endView()
if __name__ == "__main__":
#running controller function
start()
यह पैटर्न किसी कक्षा के एक वस्तु के लिए तात्कालिकता को प्रतिबंधित करता है। यह एक प्रकार का रचनात्मक पैटर्न है और इसमें केवल एक वर्ग है जिसमें विधियाँ और निर्दिष्ट वस्तुएँ बनाई जा सकती हैं।
यह निर्मित उदाहरण के लिए एक वैश्विक बिंदु प्रदान करता है।
एकल वर्ग को कैसे लागू किया जाए?
निम्नलिखित कार्यक्रम एकल वर्ग के कार्यान्वयन को प्रदर्शित करता है जहां यह कई बार बनाए गए उदाहरणों को प्रिंट करता है।
class Singleton:
__instance = None
@staticmethod
def getInstance():
""" Static access method. """
if Singleton.__instance == None:
Singleton()
return Singleton.__instance
def __init__(self):
""" Virtually private constructor. """
if Singleton.__instance != None:
raise Exception("This class is a singleton!")
else:
Singleton.__instance = self
s = Singleton()
print s
s = Singleton.getInstance()
print s
s = Singleton.getInstance()
print s
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
निर्मित उदाहरणों की संख्या समान है और आउटपुट में सूचीबद्ध वस्तुओं में कोई अंतर नहीं है।
फैक्टरी पैटर्न रचनात्मक पैटर्न सूची श्रेणी के अंतर्गत आता है। यह एक वस्तु बनाने के लिए सर्वोत्तम तरीकों में से एक प्रदान करता है। फ़ैक्टरी पैटर्न में, क्लाइंट के तर्क को उजागर किए बिना और एक सामान्य इंटरफ़ेस का उपयोग करके नए बनाए गए ऑब्जेक्ट का उल्लेख किए बिना ऑब्जेक्ट बनाए जाते हैं।
फैक्ट्री पद्धति का उपयोग करके फैक्ट्री पैटर्न को पायथन में लागू किया जाता है। जब कोई उपयोगकर्ता एक ऐसी विधि कहता है, जिसे हम एक स्ट्रिंग में पास करते हैं और एक नए ऑब्जेक्ट के रूप में रिटर्न वैल्यू को फैक्ट्री विधि के माध्यम से लागू किया जाता है। फैक्ट्री विधि में प्रयुक्त वस्तु का प्रकार स्ट्रिंग द्वारा निर्धारित किया जाता है जो विधि से गुजरता है।
नीचे दिए गए उदाहरण में, प्रत्येक विधि में ऑब्जेक्ट को एक पैरामीटर के रूप में शामिल किया गया है, जिसे फ़ैक्टरी विधि के माध्यम से लागू किया गया है।
फ़ैक्टरी पैटर्न को कैसे लागू किया जाए?
आइए अब देखते हैं कि फ़ैक्टरी पैटर्न को कैसे लागू किया जाए।
class Button(object):
html = ""
def get_html(self):
return self.html
class Image(Button):
html = "<img></img>"
class Input(Button):
html = "<input></input>"
class Flash(Button):
html = "<obj></obj>"
class ButtonFactory():
def create_button(self, typ):
targetclass = typ.capitalize()
return globals()[targetclass]()
button_obj = ButtonFactory()
button = ['image', 'input', 'flash']
for b in button:
print button_obj.create_button(b).get_html()
बटन वर्ग html टैग और संबंधित HTML पृष्ठ बनाने में मदद करता है। क्लाइंट के पास कोड के तर्क तक पहुंच नहीं होगी और आउटपुट html पेज के निर्माण का प्रतिनिधित्व करता है।
उत्पादन
व्याख्या
अजगर कोड में html टैग्स के तर्क शामिल हैं, जो मूल्य निर्दिष्ट करता है। अंतिम उपयोगकर्ता की पायथन कोड द्वारा बनाई गई HTML फ़ाइल पर एक नज़र हो सकती है।
बिल्डर पैटर्न एक अद्वितीय डिजाइन पैटर्न है जो सरल वस्तुओं का उपयोग करके जटिल वस्तु के निर्माण में मदद करता है और एक एल्गोरिथम दृष्टिकोण का उपयोग करता है। यह डिज़ाइन पैटर्न क्रिएशनल पैटर्न की श्रेणी में आता है। इस डिज़ाइन पैटर्न में, एक बिल्डर वर्ग चरण-दर-चरण प्रक्रिया में अंतिम ऑब्जेक्ट बनाता है। यह बिल्डर अन्य वस्तुओं से स्वतंत्र है।
बिल्डर पैटर्न के लाभ
यह स्पष्ट अलगाव और निर्माण और वर्ग द्वारा बनाई गई एक निर्दिष्ट वस्तु के प्रतिनिधित्व के बीच एक अनूठी परत प्रदान करता है।
यह निर्मित पैटर्न की निर्माण प्रक्रिया पर बेहतर नियंत्रण प्रदान करता है।
यह वस्तुओं के आंतरिक प्रतिनिधित्व को बदलने के लिए सही परिदृश्य देता है।
बिल्डर पैटर्न कैसे लागू करें?
इस खंड में, हम सीखेंगे कि बिल्डर पैटर्न को कैसे लागू किया जाए।
class Director:
__builder = None
def setBuilder(self, builder):
self.__builder = builder
def getCar(self):
car = Car()
# First goes the body
body = self.__builder.getBody()
car.setBody(body)
# Then engine
engine = self.__builder.getEngine()
car.setEngine(engine)
# And four wheels
i = 0
while i < 4:
wheel = self.__builder.getWheel()
car.attachWheel(wheel)
i += 1
return car
# The whole product
class Car:
def __init__(self):
self.__wheels = list()
self.__engine = None
self.__body = None
def setBody(self, body):
self.__body = body
def attachWheel(self, wheel):
self.__wheels.append(wheel)
def setEngine(self, engine):
self.__engine = engine
def specification(self):
print "body: %s" % self.__body.shape
print "engine horsepower: %d" % self.__engine.horsepower
print "tire size: %d\'" % self.__wheels[0].size
class Builder:
def getWheel(self): pass
def getEngine(self): pass
def getBody(self): pass
class JeepBuilder(Builder):
def getWheel(self):
wheel = Wheel()
wheel.size = 22
return wheel
def getEngine(self):
engine = Engine()
engine.horsepower = 400
return engine
def getBody(self):
body = Body()
body.shape = "SUV"
return body
# Car parts
class Wheel:
size = None
class Engine:
horsepower = None
class Body:
shape = None
def main():
jeepBuilder = JeepBuilder() # initializing the class
director = Director()
# Build Jeep
print "Jeep"
director.setBuilder(jeepBuilder)
jeep = director.getCar()
jeep.specification()
print ""
if __name__ == "__main__":
main()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
प्रोटोटाइप डिजाइन पैटर्न वर्ग द्वारा निर्मित उदाहरणों की जटिलता को छिपाने में मदद करता है। मौजूदा ऑब्जेक्ट की अवधारणा नई ऑब्जेक्ट के साथ अलग होगी, जो खरोंच से बनाई गई है।
नए कॉपी किए गए ऑब्जेक्ट में आवश्यक होने पर गुणों में कुछ बदलाव हो सकते हैं। यह दृष्टिकोण किसी उत्पाद के विकास के लिए जाने वाले समय और संसाधनों को बचाता है।
एक प्रोटोटाइप पैटर्न कैसे लागू करें?
आइए अब देखते हैं कि एक प्रोटोटाइप पैटर्न कैसे लागू किया जाए।
import copy
class Prototype:
_type = None
_value = None
def clone(self):
pass
def getType(self):
return self._type
def getValue(self):
return self._value
class Type1(Prototype):
def __init__(self, number):
self._type = "Type1"
self._value = number
def clone(self):
return copy.copy(self)
class Type2(Prototype):
""" Concrete prototype. """
def __init__(self, number):
self._type = "Type2"
self._value = number
def clone(self):
return copy.copy(self)
class ObjectFactory:
""" Manages prototypes.
Static factory, that encapsulates prototype
initialization and then allows instatiation
of the classes from these prototypes.
"""
__type1Value1 = None
__type1Value2 = None
__type2Value1 = None
__type2Value2 = None
@staticmethod
def initialize():
ObjectFactory.__type1Value1 = Type1(1)
ObjectFactory.__type1Value2 = Type1(2)
ObjectFactory.__type2Value1 = Type2(1)
ObjectFactory.__type2Value2 = Type2(2)
@staticmethod
def getType1Value1():
return ObjectFactory.__type1Value1.clone()
@staticmethod
def getType1Value2():
return ObjectFactory.__type1Value2.clone()
@staticmethod
def getType2Value1():
return ObjectFactory.__type2Value1.clone()
@staticmethod
def getType2Value2():
return ObjectFactory.__type2Value2.clone()
def main():
ObjectFactory.initialize()
instance = ObjectFactory.getType1Value1()
print "%s: %s" % (instance.getType(), instance.getValue())
instance = ObjectFactory.getType1Value2()
print "%s: %s" % (instance.getType(), instance.getValue())
instance = ObjectFactory.getType2Value1()
print "%s: %s" % (instance.getType(), instance.getValue())
instance = ObjectFactory.getType2Value2()
print "%s: %s" % (instance.getType(), instance.getValue())
if __name__ == "__main__":
main()
उत्पादन
उपरोक्त कार्यक्रम निम्न आउटपुट उत्पन्न करेगा -
आउटपुट मौजूदा वस्तुओं के साथ नई वस्तुओं को बनाने में मदद करता है और यह ऊपर वर्णित आउटपुट में स्पष्ट रूप से दिखाई देता है।
मुखौटा डिजाइन पैटर्न एक सबसिस्टम में इंटरफेस के एक सेट को एकीकृत इंटरफ़ेस प्रदान करता है। यह उच्च-स्तरीय इंटरफ़ेस को परिभाषित करता है जिसे कोई भी सबसिस्टम उपयोग कर सकता है।
एक मुखौटा वर्ग जानता है कि किस उप-प्रणाली अनुरोध के लिए जिम्मेदार है।
कैसे एक मुखौटा पैटर्न डिजाइन करने के लिए?
आइए अब देखते हैं कि कैसे एक मुखौटा पैटर्न डिजाइन करना है।
class _IgnitionSystem(object):
@staticmethod
def produce_spark():
return True
class _Engine(object):
def __init__(self):
self.revs_per_minute = 0
def turnon(self):
self.revs_per_minute = 2000
def turnoff(self):
self.revs_per_minute = 0
class _FuelTank(object):
def __init__(self, level=30):
self._level = level
@property
def level(self):
return self._level
@level.setter
def level(self, level):
self._level = level
class _DashBoardLight(object):
def __init__(self, is_on=False):
self._is_on = is_on
def __str__(self):
return self.__class__.__name__
@property
def is_on(self):
return self._is_on
@is_on.setter
def is_on(self, status):
self._is_on = status
def status_check(self):
if self._is_on:
print("{}: ON".format(str(self)))
else:
print("{}: OFF".format(str(self)))
class _HandBrakeLight(_DashBoardLight):
pass
class _FogLampLight(_DashBoardLight):
pass
class _Dashboard(object):
def __init__(self):
self.lights = {"handbreak": _HandBrakeLight(), "fog": _FogLampLight()}
def show(self):
for light in self.lights.values():
light.status_check()
# Facade
class Car(object):
def __init__(self):
self.ignition_system = _IgnitionSystem()
self.engine = _Engine()
self.fuel_tank = _FuelTank()
self.dashboard = _Dashboard()
@property
def km_per_litre(self):
return 17.0
def consume_fuel(self, km):
litres = min(self.fuel_tank.level, km / self.km_per_litre)
self.fuel_tank.level -= litres
def start(self):
print("\nStarting...")
self.dashboard.show()
if self.ignition_system.produce_spark():
self.engine.turnon()
else:
print("Can't start. Faulty ignition system")
def has_enough_fuel(self, km, km_per_litre):
litres_needed = km / km_per_litre
if self.fuel_tank.level > litres_needed:
return True
else:
return False
def drive(self, km = 100):
print("\n")
if self.engine.revs_per_minute > 0:
while self.has_enough_fuel(km, self.km_per_litre):
self.consume_fuel(km)
print("Drove {}km".format(km))
print("{:.2f}l of fuel still left".format(self.fuel_tank.level))
else:
print("Can't drive. The Engine is turned off!")
def park(self):
print("\nParking...")
self.dashboard.lights["handbreak"].is_on = True
self.dashboard.show()
self.engine.turnoff()
def switch_fog_lights(self, status):
print("\nSwitching {} fog lights...".format(status))
boolean = True if status == "ON" else False
self.dashboard.lights["fog"].is_on = boolean
self.dashboard.show()
def fill_up_tank(self):
print("\nFuel tank filled up!")
self.fuel_tank.level = 100
# the main function is the Client
def main():
car = Car()
car.start()
car.drive()
car.switch_fog_lights("ON")
car.switch_fog_lights("OFF")
car.park()
car.fill_up_tank()
car.drive()
car.start()
car.drive()
if __name__ == "__main__":
main()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
यह कार्यक्रम एक परिदृश्य के साथ बनाया गया है। यह कार या किसी भी ड्राइविंग वाहन के इंजन को शुरू करने के लिए है। यदि आप कोड का निरीक्षण करते हैं, तो इसमें ड्राइव करने, पार्क करने और साथ ही ईंधन का उपभोग करने के लिए संबंधित कार्य शामिल हैं।
कमांड पैटर्न क्रियाओं के बीच अमूर्तता का स्तर जोड़ता है और इसमें एक ऑब्जेक्ट शामिल होता है, जो इन कार्यों को आमंत्रित करता है।
इस डिज़ाइन पैटर्न में, क्लाइंट एक कमांड ऑब्जेक्ट बनाता है जिसमें निष्पादित करने के लिए कमांड की एक सूची शामिल होती है। कमांड ऑब्जेक्ट ने एक विशिष्ट इंटरफ़ेस लागू किया।
कमांड पैटर्न की मूल संरचना निम्नलिखित है -
कमांड पैटर्न कैसे लागू करें?
अब हम देखेंगे कि डिज़ाइन पैटर्न को कैसे लागू किया जाए।
def demo(a,b,c):
print 'a:',a
print 'b:',b
print 'c:',c
class Command:
def __init__(self, cmd, *args):
self._cmd=cmd
self._args=args
def __call__(self, *args):
return apply(self._cmd, self._args+args)
cmd = Command(dir,__builtins__)
print cmd()
cmd = Command(demo,1,2)
cmd(3)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
आउटपुट पायथन भाषा में सूचीबद्ध सभी कमांड और कीवर्ड को लागू करता है। यह चर के आवश्यक मूल्यों को प्रिंट करता है।
एडाप्टर पैटर्न दो असंगत इंटरफेस के बीच एक सेतु का काम करता है। इस प्रकार का डिज़ाइन पैटर्न संरचनात्मक पैटर्न के अंतर्गत आता है क्योंकि यह पैटर्न दो स्वतंत्र इंटरफेस की क्षमता को जोड़ता है।
इस पैटर्न में एक एकल वर्ग शामिल है, जो स्वतंत्र या असंगत इंटरफेस की कार्यक्षमता में शामिल होने के लिए जिम्मेदार है। वास्तविक जीवन का उदाहरण कार्ड रीडर का मामला हो सकता है, जो मेमोरी कार्ड और लैपटॉप के बीच एक एडेप्टर के रूप में कार्य करता है। आप मेमोरी कार्ड में कार्ड रीडर और कार्ड रीडर को लैपटॉप में प्लग करते हैं ताकि लैपटॉप के माध्यम से मेमोरी कार्ड को पढ़ा जा सके।
एडेप्टर डिज़ाइन पैटर्न कक्षाओं को एक साथ काम करने में मदद करता है। यह आवश्यकता के आधार पर एक वर्ग के इंटरफ़ेस को दूसरे इंटरफ़ेस में परिवर्तित करता है। पैटर्न में एक सट्टेबाजी एक बहुरूपता शामिल है जो एक नाम और कई रूपों का नाम देती है। एक आकार वर्ग के लिए कहो जो इकट्ठा की गई आवश्यकताओं के अनुसार उपयोग कर सकता है।
एडाप्टर पैटर्न दो प्रकार के होते हैं -
ऑब्जेक्ट एडाप्टर पैटर्न
यह डिज़ाइन पैटर्न ऑब्जेक्ट कार्यान्वयन पर निर्भर करता है। इसलिए, इसे ऑब्जेक्ट एडेप्टर पैटर्न कहा जाता है।
कक्षा एडाप्टर पैटर्न
यह एडेप्टर डिज़ाइन पैटर्न को लागू करने का एक वैकल्पिक तरीका है। पैटर्न को कई विरासतों का उपयोग करके लागू किया जा सकता है।
एडेप्टर पैटर्न को कैसे लागू किया जाए?
आइए अब देखते हैं कि एडेप्टर पैटर्न को कैसे लागू किया जाए।
class EuropeanSocketInterface:
def voltage(self): pass
def live(self): pass
def neutral(self): pass
def earth(self): pass
# Adaptee
class Socket(EuropeanSocketInterface):
def voltage(self):
return 230
def live(self):
return 1
def neutral(self):
return -1
def earth(self):
return 0
# Target interface
class USASocketInterface:
def voltage(self): pass
def live(self): pass
def neutral(self): pass
# The Adapter
class Adapter(USASocketInterface):
__socket = None
def __init__(self, socket):
self.__socket = socket
def voltage(self):
return 110
def live(self):
return self.__socket.live()
def neutral(self):
return self.__socket.neutral()
# Client
class ElectricKettle:
__power = None
def __init__(self, power):
self.__power = power
def boil(self):
if self.__power.voltage() > 110:
print "Kettle on fire!"
else:
if self.__power.live() == 1 and \
self.__power.neutral() == -1:
print "Coffee time!"
else:
print "No power."
def main():
# Plug in
socket = Socket()
adapter = Adapter(socket)
kettle = ElectricKettle(adapter)
# Make coffee
kettle.boil()
return 0
if __name__ == "__main__":
main()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
कोड में विभिन्न मापदंडों और विशेषताओं के साथ एडाप्टर इंटरफ़ेस शामिल है। इसमें टारगेट इंटरफ़ेस के साथ एडापेटी शामिल है जो सभी विशेषताओं को लागू करता है और आउटपुट को प्रदर्शित करता है।
डेकोरेटर पैटर्न किसी उपयोगकर्ता को अपनी संरचना में बदलाव किए बिना किसी मौजूदा ऑब्जेक्ट में नई कार्यक्षमता जोड़ने की अनुमति देता है। इस प्रकार का डिज़ाइन पैटर्न संरचनात्मक पैटर्न के अंतर्गत आता है क्योंकि यह पैटर्न मौजूदा वर्ग के आवरण के रूप में कार्य करता है।
यह पैटर्न एक डेकोरेटर वर्ग बनाता है, जो मूल वर्ग को लपेटता है और कक्षा के तरीकों के हस्ताक्षर को बरकरार रखते हुए अतिरिक्त कार्यक्षमता प्रदान करता है।
डेकोरेटर पैटर्न का उद्देश्य गतिशील रूप से किसी ऑब्जेक्ट की अतिरिक्त जिम्मेदारियों को जोड़ना है।
डेकोरेटर डिजाइन पैटर्न कैसे लागू करें
नीचे उल्लिखित कोड पायथन में सज्जाकार डिजाइन पैटर्न को लागू करने का एक सरल प्रदर्शन है। चित्रण में क्लास के प्रारूप में एक कॉफी शॉप का प्रदर्शन शामिल है। बनाई गई कॉफी क्लास एक सार है, जिसका अर्थ है कि यह तुरंत नहीं किया जा सकता है।
import six
from abc import ABCMeta
@six.add_metaclass(ABCMeta)
class Abstract_Coffee(object):
def get_cost(self):
pass
def get_ingredients(self):
pass
def get_tax(self):
return 0.1*self.get_cost()
class Concrete_Coffee(Abstract_Coffee):
def get_cost(self):
return 1.00
def get_ingredients(self):
return 'coffee'
@six.add_metaclass(ABCMeta)
class Abstract_Coffee_Decorator(Abstract_Coffee):
def __init__(self,decorated_coffee):
self.decorated_coffee = decorated_coffee
def get_cost(self):
return self.decorated_coffee.get_cost()
def get_ingredients(self):
return self.decorated_coffee.get_ingredients()
class Sugar(Abstract_Coffee_Decorator):
def __init__(self,decorated_coffee):
Abstract_Coffee_Decorator.__init__(self,decorated_coffee)
def get_cost(self):
return self.decorated_coffee.get_cost()
def get_ingredients(self):
return self.decorated_coffee.get_ingredients() + ', sugar'
class Milk(Abstract_Coffee_Decorator):
def __init__(self,decorated_coffee):
Abstract_Coffee_Decorator.__init__(self,decorated_coffee)
def get_cost(self):
return self.decorated_coffee.get_cost() + 0.25
def get_ingredients(self):
return self.decorated_coffee.get_ingredients() + ', milk'
class Vanilla(Abstract_Coffee_Decorator):
def __init__(self,decorated_coffee):
Abstract_Coffee_Decorator.__init__(self,decorated_coffee)
def get_cost(self):
return self.decorated_coffee.get_cost() + 0.75
def get_ingredients(self):
return self.decorated_coffee.get_ingredients() + ', vanilla'
कॉफ़ी शॉप के अमूर्त वर्ग का कार्यान्वयन नीचे उल्लिखित एक अलग फ़ाइल के साथ किया जाता है -
import coffeeshop
myCoffee = coffeeshop.Concrete_Coffee()
print('Ingredients: '+myCoffee.get_ingredients()+
'; Cost: '+str(myCoffee.get_cost())+'; sales tax = '+str(myCoffee.get_tax()))
myCoffee = coffeeshop.Milk(myCoffee)
print('Ingredients: '+myCoffee.get_ingredients()+
'; Cost: '+str(myCoffee.get_cost())+'; sales tax = '+str(myCoffee.get_tax()))
myCoffee = coffeeshop.Vanilla(myCoffee)
print('Ingredients: '+myCoffee.get_ingredients()+
'; Cost: '+str(myCoffee.get_cost())+'; sales tax = '+str(myCoffee.get_tax()))
myCoffee = coffeeshop.Sugar(myCoffee)
print('Ingredients: '+myCoffee.get_ingredients()+
'; Cost: '+str(myCoffee.get_cost())+'; sales tax = '+str(myCoffee.get_tax()))
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
प्रॉक्सी डिज़ाइन पैटर्न में एक नया ऑब्जेक्ट शामिल है, जिसे मौजूदा ऑब्जेक्ट के स्थान पर "प्रॉक्सी" कहा जाता है जिसे "रियल सब्जेक्ट" कहा जाता है। वास्तविक विषय से निर्मित प्रॉक्सी वस्तु एक ही इंटरफ़ेस पर इस तरह से होनी चाहिए कि क्लाइंट को यह पता न चले कि असली वस्तु के स्थान पर प्रॉक्सी का उपयोग किया गया है। क्लाइंट द्वारा प्रॉक्सी को दिए गए अनुरोधों को वास्तविक विषय के माध्यम से पारित किया जाता है।
प्रॉक्सी पैटर्न का UML प्रतिनिधित्व इस प्रकार है -
प्रॉक्सी पैटर्न कैसे लागू करें?
आइए अब देखते हैं कि प्रॉक्सी पैटर्न को कैसे लागू किया जाए।
class Image:
def __init__( self, filename ):
self._filename = filename
def load_image_from_disk( self ):
print("loading " + self._filename )
def display_image( self ):
print("display " + self._filename)
class Proxy:
def __init__( self, subject ):
self._subject = subject
self._proxystate = None
class ProxyImage( Proxy ):
def display_image( self ):
if self._proxystate == None:
self._subject.load_image_from_disk()
self._proxystate = 1
print("display " + self._subject._filename )
proxy_image1 = ProxyImage ( Image("HiRes_10Mb_Photo1") )
proxy_image2 = ProxyImage ( Image("HiRes_10Mb_Photo2") )
proxy_image1.display_image() # loading necessary
proxy_image1.display_image() # loading unnecessary
proxy_image2.display_image() # loading necessary
proxy_image2.display_image() # loading unnecessary
proxy_image1.display_image() # loading unnecessary
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
प्रॉक्सी पैटर्न डिज़ाइन हमारे द्वारा बनाई गई छवियों को दोहराने में मदद करता है। Display_image () फ़ंक्शन यह जांचने में मदद करता है कि मान प्रॉम्प्ट में प्रिंट हो रहे हैं या नहीं।
जिम्मेदारी पैटर्न की श्रृंखला का उपयोग सॉफ्टवेयर में ढीले युग्मन को प्राप्त करने के लिए किया जाता है जहां क्लाइंट से एक निर्दिष्ट अनुरोध इसमें शामिल वस्तुओं की एक श्रृंखला के माध्यम से पारित किया जाता है। यह वस्तुओं की एक श्रृंखला बनाने में मदद करता है। अनुरोध एक सिरे से प्रवेश करता है और एक वस्तु से दूसरी वस्तु में जाता है।
यह पैटर्न किसी वस्तु को आदेश भेजने के लिए अनुमति देता है बिना यह जाने कि कौन सी वस्तु अनुरोध को संभाल लेगी।
जिम्मेदारी पैटर्न की श्रृंखला कैसे लागू करें?
अब हम देखेंगे कि जिम्मेदारी पैटर्न की श्रृंखला को कैसे लागू किया जाए।
class ReportFormat(object):
PDF = 0
TEXT = 1
class Report(object):
def __init__(self, format_):
self.title = 'Monthly report'
self.text = ['Things are going', 'really, really well.']
self.format_ = format_
class Handler(object):
def __init__(self):
self.nextHandler = None
def handle(self, request):
self.nextHandler.handle(request)
class PDFHandler(Handler):
def handle(self, request):
if request.format_ == ReportFormat.PDF:
self.output_report(request.title, request.text)
else:
super(PDFHandler, self).handle(request)
def output_report(self, title, text):
print '<html>'
print ' <head>'
print ' <title>%s</title>' % title
print ' </head>'
print ' <body>'
for line in text:
print ' <p>%s' % line
print ' </body>'
print '</html>'
class TextHandler(Handler):
def handle(self, request):
if request.format_ == ReportFormat.TEXT:
self.output_report(request.title, request.text)
else:
super(TextHandler, self).handle(request)
def output_report(self, title, text):
print 5*'*' + title + 5*'*'
for line in text:
print line
class ErrorHandler(Handler):
def handle(self, request):
print "Invalid request"
if __name__ == '__main__':
report = Report(ReportFormat.TEXT)
pdf_handler = PDFHandler()
text_handler = TextHandler()
pdf_handler.nextHandler = text_handler
text_handler.nextHandler = ErrorHandler()
pdf_handler.handle(report)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
उपरोक्त कोड मासिक कार्यों के लिए एक रिपोर्ट बनाता है जहां यह प्रत्येक फ़ंक्शन के माध्यम से कमांड भेजता है। यह दो हैंडलर लेता है - पीडीएफ के लिए और टेक्स्ट के लिए। एक बार आवश्यक वस्तु के प्रत्येक फंक्शन को निष्पादित करने के बाद यह आउटपुट प्रिंट करता है।
इस पैटर्न में, वस्तुओं को पर्यवेक्षकों के रूप में दर्शाया जाता है जो किसी घटना के ट्रिगर होने का इंतजार करते हैं। निर्दिष्ट घटना होने पर एक पर्यवेक्षक विषय से जुड़ जाता है। जैसा कि घटना होती है, विषय पर्यवेक्षकों को बताता है कि यह हुआ है।
निम्नलिखित यूएमएल आरेख पर्यवेक्षक पैटर्न का प्रतिनिधित्व करता है -
पर्यवेक्षक पैटर्न को कैसे लागू किया जाए?
आइए अब देखते हैं कि पर्यवेक्षक पैटर्न को कैसे लागू किया जाए।
import threading
import time
import pdb
class Downloader(threading.Thread):
def run(self):
print 'downloading'
for i in range(1,5):
self.i = i
time.sleep(2)
print 'unfunf'
return 'hello world'
class Worker(threading.Thread):
def run(self):
for i in range(1,5):
print 'worker running: %i (%i)' % (i, t.i)
time.sleep(1)
t.join()
print 'done'
t = Downloader()
t.start()
time.sleep(1)
t1 = Worker()
t1.start()
t2 = Worker()
t2.start()
t3 = Worker()
t3.start()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
उपरोक्त कोड किसी विशेष परिणाम को डाउनलोड करने की प्रक्रिया को समझाता है। पर्यवेक्षक पैटर्न तर्क के अनुसार, प्रत्येक वस्तु को पर्यवेक्षक के रूप में माना जाता है। जब इवेंट ट्रिगर हो जाता है तो यह आउटपुट प्रिंट करता है।
यह राज्य मशीनों के लिए एक मॉड्यूल प्रदान करता है, जो एक निर्दिष्ट राज्य मशीन वर्ग से प्राप्त उपवर्गों का उपयोग करके कार्यान्वित किया जाता है। विधियां स्वतंत्र हैं और सज्जाकारों का उपयोग करके घोषित संक्रमण का कारण हैं।
राज्य पैटर्न को कैसे लागू किया जाए?
राज्य पैटर्न का मूल कार्यान्वयन नीचे दिखाया गया है -
class ComputerState(object):
name = "state"
allowed = []
def switch(self, state):
""" Switch to new state """
if state.name in self.allowed:
print 'Current:',self,' => switched to new state',state.name
self.__class__ = state
else:
print 'Current:',self,' => switching to',state.name,'not possible.'
def __str__(self):
return self.name
class Off(ComputerState):
name = "off"
allowed = ['on']
class On(ComputerState):
""" State of being powered on and working """
name = "on"
allowed = ['off','suspend','hibernate']
class Suspend(ComputerState):
""" State of being in suspended mode after switched on """
name = "suspend"
allowed = ['on']
class Hibernate(ComputerState):
""" State of being in hibernation after powered on """
name = "hibernate"
allowed = ['on']
class Computer(object):
""" A class representing a computer """
def __init__(self, model='HP'):
self.model = model
# State of the computer - default is off.
self.state = Off()
def change(self, state):
""" Change state """
self.state.switch(state)
if __name__ == "__main__":
comp = Computer()
comp.change(On)
comp.change(Off)
comp.change(On)
comp.change(Suspend)
comp.change(Hibernate)
comp.change(On)
comp.change(Off)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
रणनीति पैटर्न एक प्रकार का व्यवहार पैटर्न है। रणनीति पैटर्न का मुख्य लक्ष्य क्लाइंट को निर्दिष्ट कार्य को पूरा करने के लिए विभिन्न एल्गोरिदम या प्रक्रियाओं से चुनने में सक्षम बनाना है। उल्लिखित कार्य के लिए विभिन्न एल्गोरिदम को बिना किसी जटिलता के अंदर और बाहर स्वैप किया जा सकता है।
इस पैटर्न का उपयोग लचीलेपन में सुधार के लिए किया जा सकता है जब बाहरी संसाधनों तक पहुँचा जाता है।
रणनीति पैटर्न को कैसे लागू किया जाए?
नीचे दिखाया गया कार्यक्रम रणनीति पैटर्न को लागू करने में मदद करता है।
import types
class StrategyExample:
def __init__(self, func = None):
self.name = 'Strategy Example 0'
if func is not None:
self.execute = types.MethodType(func, self)
def execute(self):
print(self.name)
def execute_replacement1(self):
print(self.name + 'from execute 1')
def execute_replacement2(self):
print(self.name + 'from execute 2')
if __name__ == '__main__':
strat0 = StrategyExample()
strat1 = StrategyExample(execute_replacement1)
strat1.name = 'Strategy Example 1'
strat2 = StrategyExample(execute_replacement2)
strat2.name = 'Strategy Example 2'
strat0.execute()
strat1.execute()
strat2.execute()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
यह फ़ंक्शन से रणनीतियों की एक सूची प्रदान करता है, जो आउटपुट को निष्पादित करते हैं। इस व्यवहार पैटर्न का प्रमुख फोकस व्यवहार है।
एक टेम्पलेट पैटर्न सार ऑपरेशन का उपयोग करके आधार वर्ग में एक बुनियादी एल्गोरिथ्म को परिभाषित करता है जहां उपवर्ग ठोस व्यवहार को ओवरराइड करता है। टेम्पलेट पैटर्न एल्गोरिथ्म की रूपरेखा को एक अलग विधि में रखता है। इस विधि को टेम्पलेट विधि के रूप में संदर्भित किया जाता है।
टेम्पलेट पैटर्न की विभिन्न विशेषताएं निम्नलिखित हैं -
यह एक ऑपरेशन में एल्गोरिथ्म के कंकाल को परिभाषित करता है
इसमें उप-वर्ग शामिल हैं, जो एक एल्गोरिथ्म के कुछ चरणों को फिर से परिभाषित करता है।
class MakeMeal:
def prepare(self): pass
def cook(self): pass
def eat(self): pass
def go(self):
self.prepare()
self.cook()
self.eat()
class MakePizza(MakeMeal):
def prepare(self):
print "Prepare Pizza"
def cook(self):
print "Cook Pizza"
def eat(self):
print "Eat Pizza"
class MakeTea(MakeMeal):
def prepare(self):
print "Prepare Tea"
def cook(self):
print "Cook Tea"
def eat(self):
print "Eat Tea"
makePizza = MakePizza()
makePizza.go()
print 25*"+"
makeTea = MakeTea()
makeTea.go()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
यह कोड भोजन तैयार करने के लिए एक टेम्पलेट बनाता है। यहां, प्रत्येक पैरामीटर भोजन का एक हिस्सा बनाने के लिए विशेषता का प्रतिनिधित्व करता है जैसे कि चाय, पिज्जा, आदि।
आउटपुट विशेषताओं के विज़ुअलाइज़ेशन का प्रतिनिधित्व करता है।
फ्लाईवेट पैटर्ब संरचनात्मक डिजाइन पैटर्न श्रेणी के अंतर्गत आता है। यह ऑब्जेक्ट काउंट को कम करने का एक तरीका प्रदान करता है। इसमें विभिन्न विशेषताएं शामिल हैं जो एप्लिकेशन संरचना को बेहतर बनाने में मदद करती हैं। फ्लाईवेट ऑब्जेक्ट्स की सबसे महत्वपूर्ण विशेषता अपरिवर्तनीय है। इसका मतलब है कि निर्माण के बाद उन्हें संशोधित नहीं किया जा सकता है। संदर्भ वस्तुओं को संग्रहीत करने के लिए पैटर्न एक HashMap का उपयोग करता है।
फ्लाईवेट पैटर्न कैसे लागू करें?
निम्न कार्यक्रम फ्लाईवेट पैटर्न को लागू करने में मदद करता है -
class ComplexGenetics(object):
def __init__(self):
pass
def genes(self, gene_code):
return "ComplexPatter[%s]TooHugeinSize" % (gene_code)
class Families(object):
family = {}
def __new__(cls, name, family_id):
try:
id = cls.family[family_id]
except KeyError:
id = object.__new__(cls)
cls.family[family_id] = id
return id
def set_genetic_info(self, genetic_info):
cg = ComplexGenetics()
self.genetic_info = cg.genes(genetic_info)
def get_genetic_info(self):
return (self.genetic_info)
def test():
data = (('a', 1, 'ATAG'), ('a', 2, 'AAGT'), ('b', 1, 'ATAG'))
family_objects = []
for i in data:
obj = Families(i[0], i[1])
obj.set_genetic_info(i[2])
family_objects.append(obj)
for i in family_objects:
print "id = " + str(id(i))
print i.get_genetic_info()
print "similar id's says that they are same objects "
if __name__ == '__main__':
test()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
अमूर्त कारखाना पैटर्न को कारखानों का कारखाना भी कहा जाता है। यह डिज़ाइन पैटर्न क्रिएशनल डिज़ाइन पैटर्न श्रेणी के अंतर्गत आता है। यह एक वस्तु बनाने के लिए सर्वोत्तम तरीकों में से एक प्रदान करता है।
इसमें एक इंटरफ़ेस शामिल है, जो फ़ैक्टरी से संबंधित ऑब्जेक्ट बनाने के लिए ज़िम्मेदार है।
अमूर्त कारखाना पैटर्न को कैसे लागू किया जाए?
निम्नलिखित कार्यक्रम अमूर्त कारखाने पैटर्न को लागू करने में मदद करता है।
class Window:
__toolkit = ""
__purpose = ""
def __init__(self, toolkit, purpose):
self.__toolkit = toolkit
self.__purpose = purpose
def getToolkit(self):
return self.__toolkit
def getType(self):
return self.__purpose
class GtkToolboxWindow(Window):
def __init__(self):
Window.__init__(self, "Gtk", "ToolboxWindow")
class GtkLayersWindow(Window):
def __init__(self):
Window.__init__(self, "Gtk", "LayersWindow")
class GtkMainWindow(Window):
def __init__(self):
Window.__init__(self, "Gtk", "MainWindow")
class QtToolboxWindow(Window):
def __init__(self):
Window.__init__(self, "Qt", "ToolboxWindow")
class QtLayersWindow(Window):
def __init__(self):
Window.__init__(self, "Qt", "LayersWindow")
class QtMainWindow(Window):
def __init__(self):
Window.__init__(self, "Qt", "MainWindow")
# Abstract factory class
class UIFactory:
def getToolboxWindow(self): pass
def getLayersWindow(self): pass
def getMainWindow(self): pass
class GtkUIFactory(UIFactory):
def getToolboxWindow(self):
return GtkToolboxWindow()
def getLayersWindow(self):
return GtkLayersWindow()
def getMainWindow(self):
return GtkMainWindow()
class QtUIFactory(UIFactory):
def getToolboxWindow(self):
return QtToolboxWindow()
def getLayersWindow(self):
return QtLayersWindow()
def getMainWindow(self):
return QtMainWindow()
if __name__ == "__main__":
gnome = True
kde = not gnome
if gnome:
ui = GtkUIFactory()
elif kde:
ui = QtUIFactory()
toolbox = ui.getToolboxWindow()
layers = ui.getLayersWindow()
main = ui.getMainWindow()
print "%s:%s" % (toolbox.getToolkit(), toolbox.getType())
print "%s:%s" % (layers.getToolkit(), layers.getType())
print "%s:%s" % (main.getToolkit(), main.getType())
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
उपरोक्त कार्यक्रम में, अमूर्त कारखाना प्रत्येक विंडो के लिए ऑब्जेक्ट बनाता है। यह प्रत्येक विधि के लिए कहता है, जो आउटपुट को अपेक्षित रूप से निष्पादित करता है।
ऑब्जेक्ट ओरिएंटेड पैटर्न सबसे अधिक इस्तेमाल किया जाने वाला पैटर्न है। यह पैटर्न लगभग हर प्रोग्रामिंग भाषा में पाया जा सकता है।
वस्तु उन्मुख पैटर्न को कैसे लागू किया जाए?
आइए अब देखते हैं कि वस्तु उन्मुख पैटर्न को कैसे लागू किया जाए।
class Parrot:
# class attribute
species = "bird"
# instance attribute
def __init__(self, name, age):
self.name = name
self.age = age
# instantiate the Parrot class
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)
# access the class attributes
print("Blu is a {}".format(blu.__class__.species))
print("Woo is also a {}".format(woo.__class__.species))
# access the instance attributes
print("{} is {} years old".format( blu.name, blu.age))
print("{} is {} years old".format( woo.name, woo.age))
उत्पादन
उपरोक्त कार्यक्रम निम्न आउटपुट उत्पन्न करता है
व्याख्या
कोड में वर्ग विशेषता और उदाहरण विशेषताएँ शामिल हैं, जो आउटपुट की आवश्यकता के अनुसार मुद्रित की जाती हैं। विभिन्न विशेषताएं हैं जो ऑब्जेक्ट उन्मुख पैटर्न का हिस्सा बनती हैं। सुविधाओं को अगले अध्याय में समझाया गया है।
इस अध्याय में, हम ऑब्जेक्ट ओरिएंटेड अवधारणाओं और पायथन में इसके कार्यान्वयन का उपयोग करते हुए पैटर्न पर ध्यान केंद्रित करेंगे। जब हम अपने प्रोग्राम को स्टेटमेंट्स के ब्लॉक के आसपास डिज़ाइन करते हैं, जो फ़ंक्शन के आसपास डेटा को हेरफेर करता है, तो इसे प्रक्रिया-उन्मुख प्रोग्रामिंग कहा जाता है। ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में, क्लास और ऑब्जेक्ट नामक दो मुख्य उदाहरण हैं।
कक्षाएं और ऑब्जेक्ट चर कैसे लागू करें?
वर्गों और वस्तु चर का कार्यान्वयन इस प्रकार है -
class Robot:
population = 0
def __init__(self, name):
self.name = name
print("(Initializing {})".format(self.name))
Robot.population += 1
def die(self):
print("{} is being destroyed!".format(self.name))
Robot.population -= 1
if Robot.population == 0:
print("{} was the last one.".format(self.name))
else:
print("There are still {:d} robots working.".format(
Robot.population))
def say_hi(self):
print("Greetings, my masters call me {}.".format(self.name))
@classmethod
def how_many(cls):
print("We have {:d} robots.".format(cls.population))
droid1 = Robot("R2-D2")
droid1.say_hi()
Robot.how_many()
droid2 = Robot("C-3PO")
droid2.say_hi()
Robot.how_many()
print("\nRobots can do some work here.\n")
print("Robots have finished their work. So let's destroy them.")
droid1.die()
droid2.die()
Robot.how_many()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
यह चित्रण कक्षा और वस्तु चर की प्रकृति को प्रदर्शित करने में मदद करता है।
"जनसंख्या" "रोबोट" वर्ग का है। इसलिए, इसे एक वर्ग चर या वस्तु के रूप में संदर्भित किया जाता है।
यहाँ, हम रोबोट के रूप में जनसंख्या वर्ग चर का उल्लेख करते हैं।
इटरेटर डिजाइन पैटर्न व्यवहार डिजाइन पैटर्न श्रेणी के अंतर्गत आता है। डेवलपर्स लगभग हर प्रोग्रामिंग भाषा में इट्रेटर पैटर्न में आते हैं। इस पैटर्न का उपयोग इस तरह किया जाता है कि यह अंतर्निहित परत डिजाइन को समझे बिना किसी संग्रह के तत्वों (क्रम) को क्रमिक तरीके से एक्सेस करने में मदद करता है।
इटरेटर पैटर्न कैसे लागू करें?
अब हम देखेंगे कि इटरेटर पैटर्न को कैसे लागू किया जाए।
import time
def fib():
a, b = 0, 1
while True:
yield b
a, b = b, a + b
g = fib()
try:
for e in g:
print(e)
time.sleep(1)
except KeyboardInterrupt:
print("Calculation stopped")
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
यदि आप पैटर्न पर ध्यान केंद्रित करते हैं, तो फिबोनाची श्रृंखला को पुनरावृत्त पैटर्न के साथ मुद्रित किया जाता है। उपयोगकर्ता के बलपूर्वक समाप्ति पर, निम्न आउटपुट मुद्रित किया जाता है -
व्याख्या
यह पायथन कोड इटरेटर पैटर्न का अनुसरण करता है। यहां, गिनती शुरू करने के लिए वेतन वृद्धि ऑपरेटरों का उपयोग किया जाता है। गणना उपयोगकर्ता द्वारा बलपूर्वक समाप्ति पर समाप्त होती है।
शब्दकोश डेटा संरचनाएं हैं, जिनमें एक महत्वपूर्ण मूल्य संयोजन शामिल है। इनका व्यापक रूप से JSON - जावास्क्रिप्ट ऑब्जेक्ट संकेतन के स्थान पर उपयोग किया जाता है। शब्दकोशों का उपयोग एपीआई (एप्लीकेशन प्रोग्रामिंग इंटरफेस) प्रोग्रामिंग के लिए किया जाता है। एक शब्दकोश वस्तुओं के एक सेट को वस्तुओं के दूसरे सेट में मैप करता है। शब्दकोश परस्पर हैं; इसका मतलब है कि आवश्यकताओं के आधार पर उन्हें आवश्यकतानुसार बदला जा सकता है।
पायथन में शब्दकोशों को कैसे लागू किया जाए?
निम्नलिखित कार्यक्रम पाइथन में शब्दकोशों के मूल कार्यान्वयन को इसके निर्माण से इसके कार्यान्वयन तक शुरू करता है।
# Create a new dictionary
d = dict() # or d = {}
# Add a key - value pairs to dictionary
d['xyz'] = 123
d['abc'] = 345
# print the whole dictionary
print(d)
# print only the keys
print(d.keys())
# print only values
print(d.values())
# iterate over dictionary
for i in d :
print("%s %d" %(i, d[i]))
# another method of iteration
for index, value in enumerate(d):
print (index, value , d[value])
# check if key exist 23. Python Data Structure –print('xyz' in d)
# delete the key-value pair
del d['xyz']
# check again
print("xyz" in d)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
Note −पाइथन में शब्दकोशों के कार्यान्वयन से संबंधित कमियां हैं।
कमी
डिस्क्रिप्शन अनुक्रम डेटा प्रकारों के अनुक्रम संचालन का समर्थन नहीं करता है जैसे तार, ट्यूपल्स और सूचियां। ये बिल्ट-इन मैपिंग टाइप के होते हैं।
सूचियाँ डेटा संरचना पायथन में एक बहुमुखी डेटाटाइप है, जिसे कोमा कोष्ठक के बीच अल्पविराम से अलग मूल्यों की सूची के रूप में लिखा जा सकता है।
वाक्य - विन्यास
यहाँ संरचना के लिए मूल सिंटैक्स है -
List_name = [ elements ];
यदि आप निरीक्षण करते हैं, तो सिंटैक्स को केवल अंतर के साथ सरणियों की तरह घोषित किया जाता है जिसमें सूचियों में विभिन्न डेटा प्रकारों के साथ तत्व शामिल हो सकते हैं। सरणियों में समान डेटा प्रकार के तत्व शामिल हैं। एक सूची में तार, पूर्णांक और वस्तुओं का एक संयोजन हो सकता है। स्टैक्स और कतारों के कार्यान्वयन के लिए सूचियों का उपयोग किया जा सकता है।
सूचियाँ परस्पर हैं। इन्हें जरूरत पड़ने पर बदला जा सकता है।
सूचियों को कैसे लागू करें?
निम्नलिखित कार्यक्रम सूचियों के कार्यान्वयन को दर्शाता है -
my_list = ['p','r','o','b','e']
# Output: p
print(my_list[0])
# Output: o
print(my_list[2])
# Output: e
print(my_list[4])
# Error! Only integer can be used for indexing
# my_list[4.0]
# Nested List
n_list = ["Happy", [2,0,1,5]]
# Nested indexing
# Output: a
print(n_list[0][1])
# Output: 5
print(n_list[1][3])
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
पायथन सूचियों के अंतर्निहित कार्य इस प्रकार हैं -
Append()- यह सूची के अंत में तत्व जोड़ता है।
Extend()- यह सूची के तत्वों को दूसरी सूची में जोड़ता है।
Insert()- यह एक आइटम को निर्धारित सूचकांक में सम्मिलित करता है।
Remove()- यह निर्दिष्ट सूची से तत्व को हटाता है।
Reverse()- यह सूची में तत्वों को उलट देता है।
sort() - यह कालानुक्रमिक क्रम में तत्वों को छाँटने में मदद करता है।
एक सेट को अनियंत्रित संग्रह के रूप में परिभाषित किया जा सकता है जो कि चलने योग्य, परिवर्तनशील है और इसमें डुप्लिकेट तत्वों का समावेश नहीं है। पायथन में, सेट क्लास गणितीय सेट का एक अंकन है। एक सेट का उपयोग करने का मुख्य लाभ यह है कि इसमें विशिष्ट तत्व की जांच के लिए अत्यधिक अनुकूलित विधि शामिल है।
पायथन में एक अलग श्रेणी शामिल है जिसे फ्रोजन सेट कहा जाता है। ये सेट अपरिवर्तनीय वस्तुएं हैं जो केवल एक आवश्यक परिणाम उत्पन्न करने वाले तरीकों और ऑपरेटरों का समर्थन करते हैं।
सेट कैसे लागू करें?
निम्नलिखित कार्यक्रम सेट के कार्यान्वयन में मदद करता है -
# Set in Python
# Creating two sets
set1 = set()
set2 = set()
# Adding elements to set1
for i in range(1, 6):
set1.add(i)
# Adding elements to set2
for i in range(3, 8):
set2.add(i)
print("Set1 = ", set1)
print("Set2 = ", set2)
print("\n")
# Union of set1 and set2
set3 = set1 | set2# set1.union(set2)
print("Union of Set1 & Set2: Set3 = ", set3)
# Intersection of set1 and set2
set4 = set1 & set2# set1.intersection(set2)
print("Intersection of Set1 & Set2: Set4 = ", set4)
print("\n")
# Checking relation between set3 and set4
if set3 > set4: # set3.issuperset(set4)
print("Set3 is superset of Set4")
elif set3 < set4: # set3.issubset(set4)
print("Set3 is subset of Set4")
else : # set3 == set4
print("Set3 is same as Set4")
# displaying relation between set4 and set3
if set4 < set3: # set4.issubset(set3)
print("Set4 is subset of Set3")
print("\n")
# difference between set3 and set4
set5 = set3 - set4
print("Elements in Set3 and not in Set4: Set5 = ", set5)
print("\n")
# checkv if set4 and set5 are disjoint sets
if set4.isdisjoint(set5):
print("Set4 and Set5 have nothing in common\n")
# Removing all the values of set5
set5.clear()
print("After applying clear on sets Set5: ")
print("Set5 = ", set5)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
जमे हुए सेट को निम्नलिखित कार्यक्रम का उपयोग करके दिखाया जा सकता है -
normal_set = set(["a", "b","c"])
# Adding an element to normal set is fine
normal_set.add("d")
print("Normal Set")
print(normal_set)
# A frozen set
frozen_set = frozenset(["e", "f", "g"])
print("Frozen Set")
print(frozen_set)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
कतार वस्तुओं का एक संग्रह है, जो FIFO (फास्ट इन फास्ट आउट) और LIFO (लास्ट इन फर्स्ट आउट) प्रक्रियाओं के बाद एक सरल डेटा संरचना को परिभाषित करता है। डालने और हटाने के संचालन के रूप में संदर्भित किया जाता हैenqueue तथा dequeue संचालन।
कतारें उन वस्तुओं तक यादृच्छिक पहुँच की अनुमति नहीं देती हैं जिनमें वे शामिल हैं।
FIFO प्रक्रिया कैसे लागू करें?
निम्नलिखित कार्यक्रम FIFO के कार्यान्वयन में मदद करता है -
import Queue
q = Queue.Queue()
#put items at the end of the queue
for x in range(4):
q.put("item-" + str(x))
#remove items from the head of the queue
while not q.empty():
print q.get()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
LIFO प्रक्रिया कैसे लागू करें?
निम्नलिखित कार्यक्रम LIFO प्रक्रिया के कार्यान्वयन में मदद करता है -
import Queue
q = Queue.LifoQueue()
#add items at the head of the queue
for x in range(4):
q.put("item-" + str(x))
#remove items from the head of the queue
while not q.empty():
print q.get()
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
प्राथमिकता कतार क्या है?
प्राथमिकता कतार एक कंटेनर डेटा संरचना है जो निर्दिष्ट डेटा संरचना में सबसे छोटी या सबसे बड़ी कुंजी के साथ रिकॉर्ड तक त्वरित पहुंच प्रदान करने के लिए आदेशित कुंजियों के साथ रिकॉर्ड का एक सेट प्रबंधित करती है।
प्राथमिकता कतार कैसे लागू करें?
प्राथमिकता कतार का कार्यान्वयन निम्नानुसार है -
import Queue
class Task(object):
def __init__(self, priority, name):
self.priority = priority
self.name = name
def __cmp__(self, other):
return cmp(self.priority, other.priority)
q = Queue.PriorityQueue()
q.put( Task(100, 'a not agent task') )
q.put( Task(5, 'a highly agent task') )
q.put( Task(10, 'an important task') )
while not q.empty():
cur_task = q.get()
print 'process task:', cur_task.name
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
स्ट्रिंग क्रमांकन वस्तु की स्थिति को बाइट स्ट्रीम में लिखने की प्रक्रिया है। अजगर में, "अचार" पुस्तकालय का उपयोग क्रमांकन को सक्षम करने के लिए किया जाता है। इस मॉड्यूल में पायथन ऑब्जेक्ट संरचना को क्रमांकित और डी-सीरियल करने के लिए एक शक्तिशाली एल्गोरिदम शामिल है। "अचार" पाइथन ऑब्जेक्ट पदानुक्रम को बाइट स्ट्रीम में बदलने की प्रक्रिया है और "अनप्लिकिंग" रिवर्स प्रक्रिया है।
अचार मॉड्यूल का प्रदर्शन निम्नानुसार है -
import pickle
#Here's an example dict
grades = { 'Alice': 89, 'Bob': 72, 'Charles': 87 }
#Use dumps to convert the object to a serialized string
serial_grades = pickle.dumps( grades )
print(serial_grades)
#Use loads to de-serialize an object
received_grades = pickle.loads( serial_grades )
print(received_grades)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
समरूपता को अक्सर समानता के रूप में गलत समझा जाता है। कंसीमेन्ट का तात्पर्य शेड्यूलिंग इंडिपेंडेंट कोड को व्यवस्थित तरीके से निष्पादित करना है। यह अध्याय पायथन का उपयोग करते हुए एक ऑपरेटिंग सिस्टम के लिए संगामिति के निष्पादन पर केंद्रित है।
निम्नलिखित कार्यक्रम एक ऑपरेटिंग सिस्टम के लिए संगामिति के निष्पादन में मदद करता है -
import os
import time
import threading
import multiprocessing
NUM_WORKERS = 4
def only_sleep():
print("PID: %s, Process Name: %s, Thread Name: %s" % (
os.getpid(),
multiprocessing.current_process().name,
threading.current_thread().name)
)
time.sleep(1)
def crunch_numbers():
print("PID: %s, Process Name: %s, Thread Name: %s" % (
os.getpid(),
multiprocessing.current_process().name,
threading.current_thread().name)
)
x = 0
while x < 10000000:
x += 1
for _ in range(NUM_WORKERS):
only_sleep()
end_time = time.time()
print("Serial time=", end_time - start_time)
# Run tasks using threads
start_time = time.time()
threads = [threading.Thread(target=only_sleep) for _ in range(NUM_WORKERS)]
[thread.start() for thread in threads]
[thread.join() for thread in threads]
end_time = time.time()
print("Threads time=", end_time - start_time)
# Run tasks using processes
start_time = time.time()
processes = [multiprocessing.Process(target=only_sleep()) for _ in range(NUM_WORKERS)]
[process.start() for process in processes]
[process.join() for process in processes]
end_time = time.time()
print("Parallel time=", end_time - start_time)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
व्याख्या
"मल्टीप्रोसेसिंग" थ्रेडिंग मॉड्यूल के समान एक पैकेज है। यह पैकेज लोकल और रिमोट कंसेप्ट को सपोर्ट करता है। इस मॉड्यूल के कारण, प्रोग्रामर को दिए गए सिस्टम पर कई प्रक्रियाओं का उपयोग करने का लाभ मिलता है।
एंटी-पैटर्न पूर्वनिर्धारित डिजाइन पैटर्न के विरोध में एक रणनीति का पालन करते हैं। रणनीति में सामान्य समस्याओं के लिए सामान्य दृष्टिकोण शामिल हैं, जिन्हें औपचारिक रूप दिया जा सकता है और आमतौर पर एक अच्छा विकास अभ्यास माना जा सकता है। आमतौर पर, विरोधी पैटर्न विपरीत और अवांछनीय होते हैं। एंटी-पैटर्न सॉफ्टवेयर विकास में उपयोग किए जाने वाले कुछ पैटर्न हैं, जिन्हें खराब प्रोग्रामिंग प्रथाओं के रूप में माना जाता है।
एंटी-पैटर्न की महत्वपूर्ण विशेषताएं
आइए अब हम एंटी-पैटर्न की कुछ महत्वपूर्ण विशेषताओं को देखते हैं।
यथार्थता
ये पैटर्न सचमुच आपके कोड को तोड़ते हैं और आपको गलत काम करते हैं। निम्नलिखित इसका एक सरल चित्रण है -
class Rectangle(object):
def __init__(self, width, height):
self._width = width
self._height = height
r = Rectangle(5, 6)
# direct access of protected member
print("Width: {:d}".format(r._width))
रख-रखाव
एक कार्यक्रम को बनाए रखने के लिए कहा जाता है यदि आवश्यकता के अनुसार इसे समझना और संशोधित करना आसान है। इंपोर्टिंग मॉड्यूल को मेंटेनेंस की मिसाल माना जा सकता है।
import math
x = math.ceil(y)
# or
import multiprocessing as mp
pool = mp.pool(8)
प्रतिमान का उदाहरण
उदाहरण के बाद विरोधी प्रतिमानों के प्रदर्शन में मदद मिलती है -
#Bad
def filter_for_foo(l):
r = [e for e in l if e.find("foo") != -1]
if not check_some_critical_condition(r):
return None
return r
res = filter_for_foo(["bar","foo","faz"])
if res is not None:
#continue processing
pass
#Good
def filter_for_foo(l):
r = [e for e in l if e.find("foo") != -1]
if not check_some_critical_condition(r):
raise SomeException("critical condition unmet!")
return r
try:
res = filter_for_foo(["bar","foo","faz"])
#continue processing
except SomeException:
i = 0
while i < 10:
do_something()
#we forget to increment i
व्याख्या
उदाहरण में पायथन में एक समारोह बनाने के लिए अच्छे और बुरे मानकों का प्रदर्शन शामिल है।
अपवादों को संभालना भी डिजाइन पैटर्न का एक प्राथमिक मानदंड है। एक अपवाद एक त्रुटि है जो एक कार्यक्रम के निष्पादन के दौरान होता है। जब कोई विशेष त्रुटि होती है, तो अपवाद उत्पन्न करना महत्वपूर्ण है। यह प्रोग्राम क्रैश को रोकने में मदद करता है।
अपवाद क्यों?
अपवाद एक कार्यक्रम में त्रुटियों और विशेष परिस्थितियों से निपटने के सुविधाजनक तरीके हैं। जब एक उपयोगकर्ता को लगता है कि निर्दिष्ट कोड एक त्रुटि उत्पन्न कर सकता है तो अपवाद हैंडलिंग का उपयोग करना महत्वपूर्ण है।
उदाहरण - शून्य द्वारा विभाजन
import sys
randomList = ['a', 0, 2]
for entry in randomList:
try:
print("The entry is", entry)
r = 1/int(entry)
break
except:
print("Oops!",sys.exc_info()[0],"occured.")
print("Next entry.")
print()
print("The reciprocal of",entry,"is",r)
उत्पादन
उपरोक्त कार्यक्रम निम्नलिखित आउटपुट उत्पन्न करता है -
अपवाद उठाना
पायथन प्रोग्रामिंग में, विशेष रूप से, अपवाद तब उठाए जाते हैं जब कोड के अनुरूप त्रुटि रन टाइम पर होती है। इस का उपयोग करके जबरदस्ती उठाया जा सकता है“raise” कीवर्ड।
वाक्य - विन्यास
raise KeyboardInterrupt
Traceback (most recent call last):
...
KeyboardInterrupt