Python 디자인 패턴-빠른 가이드
디자인 패턴은 개발자가 소프트웨어 또는 웹 응용 프로그램을 만드는 데 사용하는 패턴을 나타내는 데 사용됩니다. 이러한 패턴은 요구 사항 분석을 기반으로 선택됩니다. 패턴은 문제에 대한 솔루션, 솔루션을 적용 할시기 및 위치 및 구현 결과를 설명합니다.
디자인 패턴의 구조
디자인 패턴의 문서화는 사용되는 기술과 방식에 더 초점을 맞추는 방식으로 유지됩니다. 다음 다이어그램은 디자인 패턴 문서의 기본 구조를 설명합니다.
패턴 이름
짧고 효과적인 방법으로 패턴을 설명합니다.
의도 / 동기
패턴이하는 일을 설명합니다.
적용 가능성
패턴을 적용 할 수있는 상황 목록을 설명합니다.
참가자 및 결과
참여자는 패턴과 함께 존재하는 결과 목록과 함께 디자인 패턴에 참여하는 클래스 및 객체를 포함합니다.
왜 파이썬인가?
Python은 오픈 소스 스크립팅 언어입니다. 다양한 디자인 패턴을 지원하는 라이브러리가 있습니다. 파이썬의 구문은 이해하기 쉽고 영어 키워드를 사용합니다.
Python은 아래에 언급 된 디자인 패턴 목록에 대한 지원을 제공합니다. 이 디자인 패턴은이 튜토리얼 전체에서 사용됩니다.
- 모델보기 컨트롤러 패턴
- 싱글 톤 패턴
- 공장 패턴
- 빌더 패턴
- 프로토 타입 패턴
- 외관 패턴
- 명령 패턴
- 어댑터 패턴
- 프로토 타입 패턴
- 데코레이터 패턴
- 프록시 패턴
- 책임의 사슬 패턴
- 관찰자 패턴
- 상태 패턴
- 전략 패턴
- 템플릿 패턴
- 플라이 웨이트 패턴
- 추상 공장 패턴
- 객체 지향 패턴
디자인 패턴 사용의 이점
다음은 디자인 패턴의 다양한 이점입니다.
패턴은 개발자에게 지정된 문제에 대해 시도되고 테스트 된 솔루션을 제공합니다.
모든 디자인 패턴은 언어 중립적입니다.
패턴은 의사 소통을 달성하고 문서를 잘 유지하는 데 도움이됩니다.
여기에는 프로젝트에 대한 기술적 위험을 줄이기위한 성과 기록이 포함됩니다.
디자인 패턴은 사용하기 매우 유연하고 이해하기 쉽습니다.
Python은 오픈 소스 스크립팅 언어로, 고수준, 해석, 대화 형 및 객체 지향입니다. 읽기 쉽게 설계되었습니다. Python 언어의 구문은 이해하기 쉽고 영어 키워드를 자주 사용합니다.
Python 언어의 특징
이 섹션에서는 Python 언어의 다양한 기능에 대해 알아 봅니다.
해석 됨
Python은 인터프리터를 사용하여 런타임에 처리됩니다. 실행 전에 프로그램을 컴파일 할 필요가 없습니다. PERL 및 PHP와 유사합니다.
객체 지향
파이썬은 객체 지향 스타일과 디자인 패턴을 따릅니다. 캡슐화, 다형성 등과 같은 다양한 기능을 가진 클래스 정의가 포함됩니다.
가지고 다닐 수 있는
Windows 운영 체제로 작성된 Python 코드이며 Mac 운영 체제에서 사용할 수 있습니다. 코드는 요구 사항에 따라 재사용 및 이식이 가능합니다.
간편한 코딩
Python 구문은 이해하기 쉽고 코딩하기 쉽습니다. 모든 개발자는 몇 시간 내에 Python의 구문을 이해할 수 있습니다. Python은 "프로그래머 친화적"이라고 설명 할 수 있습니다.
확장 가능
필요한 경우 사용자는 C 언어로도 일부 Python 코드를 작성할 수 있습니다. C ++와 같은 다른 언어로 된 소스 코드에 파이썬 코드를 넣는 것도 가능합니다. 이것은 파이썬을 확장 가능한 언어로 만듭니다.
중요 사항
Python 프로그래밍 언어와 관련된 다음 중요한 사항을 고려하십시오.
여기에는 기능적이고 구조화 된 프로그래밍 방법과 객체 지향 프로그래밍 방법이 포함됩니다.
스크립팅 언어 또는 프로그래밍 언어로 사용할 수 있습니다.
자동 가비지 수집이 포함됩니다.
높은 수준의 동적 데이터 유형을 포함하고 다양한 동적 유형 검사를 지원합니다.
Python에는 C, C ++ 및 Java와 같은 언어와의 통합 기능이 포함되어 있습니다.
시스템에서 파이썬 언어를 다운로드하는 방법은 무엇입니까?
시스템에서 Python 언어를 다운로드하려면 다음 링크를 따르십시오.
https://www.python.org/downloads/여기에는 Windows, MacOS 및 Linux 배포판과 같은 다양한 운영 체제 용 패키지가 포함되어 있습니다.
Python의 중요한 도구
이 섹션에서는 Python의 몇 가지 중요한 도구에 대해 간략하게 배웁니다.
파이썬 문자열
문자열의 기본 선언은 다음과 같습니다.
str = 'Hello World!'
파이썬 목록
파이썬 목록은 쉼표로 구분되고 대괄호 ([])로 묶인 복합 데이터 유형으로 선언 할 수 있습니다.
list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']
Python 튜플
튜플은 Python의 동적 데이터 유형으로, 쉼표로 구분 된 여러 값으로 구성됩니다. 튜플은 괄호로 묶습니다.
tinytuple = (123, 'john')
파이썬 사전
Python 사전은 해시 테이블 유형입니다. 사전 키는 거의 모든 데이터 유형의 Python이 될 수 있습니다. 데이터 유형은 일반적으로 숫자 또는 문자열입니다.
tinydict = {'name': 'omkar','code':6734, 'dept': 'sales'}
파이썬에서 디자인 패턴을 구성하는 것은 무엇입니까?
Python은 다음 매개 변수를 사용하여 디자인 패턴을 구성하는 데 도움이됩니다.
- 패턴 이름
- Intent
- Aliases
- Motivation
- Problem
- Solution
- Structure
- Participants
- Constraints
- 샘플 코드
Model View Controller는 가장 일반적으로 사용되는 디자인 패턴입니다. 개발자는이 디자인 패턴을 쉽게 구현할 수 있습니다.
다음은 Model View Controller의 기본 아키텍처입니다.
이제 구조가 어떻게 작동하는지 살펴 보겠습니다.
모델
데이터베이스와 상호 작용하는 순수 애플리케이션 논리로 구성됩니다. 여기에는 최종 사용자에게 데이터를 나타내는 모든 정보가 포함됩니다.
전망
보기는 최종 사용자와 상호 작용하는 HTML 파일을 나타냅니다. 사용자에게 모델의 데이터를 나타냅니다.
제어 장치
뷰와 모델 사이의 중개자 역할을합니다. 뷰 및 쿼리 모델에 의해 트리거 된 이벤트를 수신합니다.
파이썬 코드
"사람"이라는 기본 개체를 고려하고 MVC 디자인 패턴을 만듭니다.
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
데이터베이스에있는 Person 테이블의 모든 레코드를 가져 오는 메소드를 호출합니다. 레코드는 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
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
생성 된 인스턴스 수는 동일하며 출력에 나열된 객체에는 차이가 없습니다.
팩토리 패턴은 생성 패턴 목록 카테고리에 속합니다. 개체를 만드는 가장 좋은 방법 중 하나를 제공합니다. 팩토리 패턴에서는 클라이언트에 로직을 노출하지 않고 공통 인터페이스를 사용하여 새로 생성 된 객체를 참조하지 않고 객체를 생성합니다.
팩토리 패턴은 팩토리 메서드를 사용하여 Python으로 구현됩니다. 사용자가 문자열을 전달하는 메서드를 호출하면 새로운 객체로 반환되는 값이 팩토리 메서드를 통해 구현됩니다. 팩토리 메소드에서 사용되는 객체의 유형은 메소드를 통해 전달되는 문자열에 의해 결정됩니다.
아래 예제에서 모든 메소드는 팩토리 메소드를 통해 구현되는 매개 변수로 객체를 포함합니다.
팩토리 패턴을 구현하는 방법은 무엇입니까?
이제 팩토리 패턴을 구현하는 방법을 살펴 보겠습니다.
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 태그의 로직을 포함합니다. 최종 사용자는 Python 코드로 생성 된 HTML 파일을 볼 수 있습니다.
Builder Pattern은 단순한 객체를 사용하여 복잡한 객체를 구축하고 알고리즘 방식을 사용하는 고유 한 디자인 패턴입니다. 이 디자인 패턴은 창조 패턴의 범주에 속합니다. 이 디자인 패턴에서 빌더 클래스는 단계별 절차에서 최종 객체를 빌드합니다. 이 빌더는 다른 개체와 독립적입니다.
빌더 패턴의 장점
클래스에 의해 생성 된 지정된 객체의 구성과 표현 사이에 명확한 분리와 고유 한 레이어를 제공합니다.
생성 된 패턴의 구성 프로세스를 더 잘 제어 할 수 있습니다.
개체의 내부 표현을 변경하는 완벽한 시나리오를 제공합니다.
빌더 패턴을 구현하는 방법은 무엇입니까?
이 섹션에서는 빌더 패턴을 구현하는 방법을 배웁니다.
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()
산출
위의 프로그램은 다음 출력을 생성합니다-
출력은 기존 개체로 새 개체를 만드는 데 도움이되며 위에서 언급 한 출력에서 명확하게 볼 수 있습니다.
Facade 디자인 패턴은 서브 시스템의 인터페이스 세트에 대한 통합 인터페이스를 제공합니다. 모든 하위 시스템에서 사용할 수있는 상위 수준 인터페이스를 정의합니다.
파사드 클래스는 어떤 서브 시스템이 요청을 담당하는지 알고 있습니다.
외관 패턴을 디자인하는 방법은 무엇입니까?
이제 파사드 패턴을 디자인하는 방법을 살펴 보겠습니다.
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)
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
설명
출력은 Python 언어로 나열된 모든 명령과 키워드를 구현합니다. 필요한 변수 값을 인쇄합니다.
어댑터 패턴은 호환되지 않는 두 인터페이스 사이의 다리 역할을합니다. 이 유형의 디자인 패턴은 두 개의 독립적 인 인터페이스의 기능을 결합하기 때문에 구조적 패턴을 따릅니다.
이 패턴은 독립적이거나 호환되지 않는 인터페이스의 기능을 결합하는 단일 클래스를 포함합니다. 실제 사례는 메모리 카드와 랩톱 사이의 어댑터 역할을하는 카드 리더의 경우 일 수 있습니다. 노트북을 통해 메모리 카드를 읽을 수 있도록 메모리 카드를 카드 리더기에 연결하고 카드 리더를 노트북에 연결합니다.
어댑터 디자인 패턴은 클래스를 함께 작업하는 데 도움이됩니다. 요구 사항에 따라 클래스의 인터페이스를 다른 인터페이스로 변환합니다. 이 패턴에는 하나의 이름과 여러 형태를 명명하는 다형성의 종화가 포함됩니다. 수집 된 요구 사항에 따라 사용할 수있는 모양 클래스를 말합니다.
어댑터 패턴에는 두 가지 유형이 있습니다.
개체 어댑터 패턴
이 디자인 패턴은 객체 구현에 의존합니다. 따라서이를 Object Adapter Pattern이라고합니다.
클래스 어댑터 패턴
이것은 어댑터 디자인 패턴을 구현하는 다른 방법입니다. 패턴은 다중 상속을 사용하여 구현할 수 있습니다.
어댑터 패턴을 구현하는 방법은 무엇입니까?
이제 어댑터 패턴을 구현하는 방법을 살펴 보겠습니다.
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()
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
설명
코드에는 다양한 매개 변수 및 속성이있는 어댑터 인터페이스가 포함됩니다. 모든 속성을 구현하고 출력을 가시적으로 표시하는 Target 인터페이스와 함께 Adaptee를 포함합니다.
데코레이터 패턴을 사용하면 사용자가 구조를 변경하지 않고 기존 객체에 새로운 기능을 추가 할 수 있습니다. 이 유형의 디자인 패턴은이 패턴이 기존 클래스의 래퍼 역할을하므로 구조적 패턴 아래에 있습니다.
이 패턴은 원래 클래스를 래핑하고 클래스 메서드 서명을 그대로 유지하는 추가 기능을 제공하는 데코레이터 클래스를 만듭니다.
데코레이터 패턴의 동기는 객체의 추가 책임을 동적으로 첨부하는 것입니다.
데코레이터 디자인 패턴을 구현하는 방법
아래에 언급 된 코드는 Python에서 데코레이터 디자인 패턴을 구현하는 방법에 대한 간단한 데모입니다. 그림에는 수업 형식의 커피 숍 시연이 포함됩니다. 생성 된 커피 클래스는 추상이므로 인스턴스화 할 수 없습니다.
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)
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
설명
위 코드는 각 기능을 통해 명령을 보내는 월별 작업 보고서를 생성합니다. PDF와 텍스트의 두 가지 핸들러가 필요합니다. 필요한 객체가 각 기능을 실행하면 출력을 인쇄합니다.
이 패턴에서 개체는 이벤트가 트리거되기를 기다리는 관찰자로 표시됩니다. 관찰자는 지정된 이벤트가 발생하면 주제에 연결합니다. 사건이 발생하면 피험자는 관찰자에게 사건이 발생했음을 알립니다.
다음 UML 다이어그램은 관찰자 패턴을 나타냅니다.
관찰자 패턴을 구현하는 방법은 무엇입니까?
이제 관찰자 패턴을 구현하는 방법을 살펴 보겠습니다.
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()
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
설명
이 코드는 식사 준비를위한 템플릿을 만듭니다. 여기에서 각 매개 변수는 차, 피자 등과 같은 식사의 일부를 생성하는 속성을 나타냅니다.
출력은 속성의 시각화를 나타냅니다.
플라이 웨이트 패턴은 구조 설계 패턴 범주에 속합니다. 개체 수를 줄이는 방법을 제공합니다. 여기에는 응용 프로그램 구조를 개선하는 데 도움이되는 다양한 기능이 포함되어 있습니다. flyweight 객체의 가장 중요한 기능은 변경 불가능합니다. 즉, 일단 구성되면 수정할 수 없습니다. 패턴은 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()
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
추상적 인 공장 패턴은 공장 공장이라고도합니다. 이 디자인 패턴은 창조 디자인 패턴 카테고리에 속합니다. 개체를 만드는 가장 좋은 방법 중 하나를 제공합니다.
Factory와 관련된 객체를 생성하는 인터페이스를 포함합니다.
추상 팩토리 패턴을 구현하는 방법은 무엇입니까?
다음 프로그램은 추상 팩토리 패턴을 구현하는 데 도움이됩니다.
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()
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
설명
이 그림은 클래스 및 개체 변수의 특성을 보여줍니다.
"인구"는 "로봇"클래스에 속합니다. 따라서 클래스 변수 또는 객체라고합니다.
여기서는 인구 클래스 변수를 self.population이 아닌 Robot.population이라고합니다.
반복기 디자인 패턴은 행동 디자인 패턴 범주에 속합니다. 개발자는 거의 모든 프로그래밍 언어에서 반복기 패턴을 접하게됩니다. 이 패턴은 기본 레이어 디자인을 이해하지 않고 순차적으로 컬렉션 (클래스)의 요소에 액세스하는 데 도움이되는 방식으로 사용됩니다.
반복기 패턴을 구현하는 방법은 무엇입니까?
이제 반복기 패턴을 구현하는 방법을 살펴 보겠습니다.
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 (JavaScript Object Notation) 대신 널리 사용됩니다. 사전은 API (Application Programming Interface) 프로그래밍에 사용됩니다. 사전은 개체 집합을 다른 개체 집합에 매핑합니다. 사전은 변경 가능합니다. 이는 요구 사항에 따라 필요할 때마다 변경할 수 있음을 의미합니다.
파이썬에서 사전을 구현하는 방법은 무엇입니까?
다음 프로그램은 생성부터 구현까지 Python의 기본 사전 구현을 보여줍니다.
# 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 −Python에서 사전 구현과 관련된 단점이 있습니다.
약점
사전은 문자열, 튜플 및 목록과 같은 시퀀스 데이터 유형의 시퀀스 작업을 지원하지 않습니다. 이들은 내장 매핑 유형에 속합니다.
Lists 데이터 구조는 Python의 다목적 데이터 유형으로, 대괄호 사이에 쉼표로 구분 된 값 목록으로 작성할 수 있습니다.
통사론
다음은 구조의 기본 구문입니다.
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() − 요소를 시간순으로 정렬하는 데 도움이됩니다.
집합은 반복 가능하고 변경 가능하며 중복 요소가 포함되지 않는 정렬되지 않은 컬렉션으로 정의 할 수 있습니다. 파이썬에서 집합 클래스는 수학적 집합의 표기법입니다. 집합 사용의 가장 큰 장점은 특정 요소를 검사하는 고도로 최적화 된 방법을 포함한다는 것입니다.
Python에는 고정 세트라는 별도의 범주가 있습니다. 이러한 집합은 필요한 결과를 생성하는 메서드와 연산자 만 지원하는 변경 불가능한 개체입니다.
세트를 구현하는 방법?
다음 프로그램은 세트 구현에 도움이됩니다-
# 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 (Fast In Fast Out) 및 LIFO (Last In First Out) 절차에 따라 간단한 데이터 구조를 정의하는 개체 모음입니다. 삽입 및 삭제 작업은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
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
문자열 직렬화는 개체의 상태를 바이트 스트림에 쓰는 프로세스입니다. 파이썬에서 "pickle"라이브러리는 직렬화를 활성화하는 데 사용됩니다. 이 모듈에는 Python 객체 구조의 직렬화 및 역 직렬화를위한 강력한 알고리즘이 포함되어 있습니다. "Pickling"은 Python 객체 계층 구조를 바이트 스트림으로 변환하는 프로세스이고 "unpickling"은 그 반대 절차입니다.
pickle 모듈의 데모는 다음과 같습니다.
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)
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
동시성은 종종 병렬 처리로 오해됩니다. 동시성은 독립적 인 코드가 체계적으로 실행되도록 스케줄링하는 것을 의미합니다. 이 장에서는 Python을 사용하는 운영 체제의 동시 실행에 중점을 둡니다.
다음 프로그램은 운영 체제의 동시 실행을 도와줍니다.
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
설명
이 예제에는 Python에서 함수를 생성하기위한 좋은 표준과 나쁜 표준의 데모가 포함되어 있습니다.
예외 처리는 디자인 패턴의 주요 기준이기도합니다. 예외는 프로그램 실행 중에 발생하는 오류입니다. 특정 오류가 발생하면 예외를 생성하는 것이 중요합니다. 이것은 프로그램 충돌을 억제하는 데 도움이됩니다.
예외를 사용하는 이유는 무엇입니까?
예외는 프로그램에서 오류 및 특수 조건을 처리하는 편리한 방법입니다. 사용자가 지정된 코드가 오류를 생성 할 수 있다고 생각하면 예외 처리를 사용하는 것이 중요합니다.
예 – 0으로 나누기
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)
산출
위의 프로그램은 다음과 같은 출력을 생성합니다-
예외 발생
특히 Python 프로그래밍에서 런타임에 해당 코드 오류가 발생하면 예외가 발생합니다. 이것은 다음을 사용하여 강제로 올릴 수 있습니다.“raise” 예어.
통사론
raise KeyboardInterrupt
Traceback (most recent call last):
...
KeyboardInterrupt