Шаблоны проектирования Python - Краткое руководство
Шаблоны проектирования используются для представления шаблона, используемого разработчиками для создания программного обеспечения или веб-приложений. Эти шаблоны выбираются на основе анализа требований. Шаблоны описывают решение проблемы, когда и где применять решение, а также последствия внедрения.
Структура шаблона проектирования
Документация по шаблону проектирования ведется таким образом, чтобы больше внимания уделялось технологиям, которые используются и каким образом. Следующая диаграмма поясняет базовую структуру документации по шаблонам проектирования.
Название шаблона
Он описывает шаблон кратко и эффективно.
Намерение / Мотив
Он описывает, что делает шаблон.
Применимость
Он описывает список ситуаций, в которых применим шаблон.
Участники и последствия
Участники включают классы и объекты, которые участвуют в шаблоне проектирования, со списком последствий, существующих в шаблоне.
Почему Python?
Python - это язык сценариев с открытым исходным кодом. В нем есть библиотеки, поддерживающие множество шаблонов проектирования. Синтаксис Python прост для понимания и использует ключевые слова на английском языке.
Python поддерживает список шаблонов проектирования, упомянутых ниже. Эти шаблоны проектирования будут использоваться в этом руководстве -
- Шаблон контроллера представления модели
- Шаблон Singleton
- Заводской образец
- Шаблон Строителя
- Образец прототипа
- Узор фасада
- Командный шаблон
- Шаблон адаптера
- Образец прототипа
- Шаблон декоратора
- Шаблон прокси
- Схема цепочки ответственности
- Шаблон наблюдателя
- Государственный образец
- Шаблон стратегии
- Шаблон шаблона
- Схема наилегчайшего веса
- Абстрактный узор фабрики
- Объектно-ориентированный узор
Преимущества использования шаблона проектирования
Ниже приведены различные преимущества шаблона проектирования.
Шаблоны предоставляют разработчику выбор проверенных решений для указанных проблем.
Все шаблоны проектирования не зависят от языка.
Шаблоны помогают достичь коммуникации и хорошо документировать.
Он включает в себя отчет о достижениях для снижения любого технического риска для проекта.
Шаблоны проектирования очень гибки в использовании и просты для понимания.
Python - это язык сценариев с открытым исходным кодом, который является высокоуровневым, интерпретируемым, интерактивным и объектно-ориентированным. Он разработан для удобочитаемости. Синтаксис языка Python прост для понимания и часто использует английские ключевые слова.
Особенности языка Python
В этом разделе мы узнаем о различных функциях языка Python.
Истолкованный
Python обрабатывается во время выполнения с помощью интерпретатора. Компилировать программу перед выполнением не нужно. Он похож на PERL и PHP.
Объектно-ориентированный
Python следует объектно-ориентированному стилю и шаблонам проектирования. Он включает определение класса с различными функциями, такими как инкапсуляция, полиморфизм и многое другое.
Портативный
Код Python написан в операционной системе Windows и может использоваться в операционной системе Mac. Код можно повторно использовать и переносить в соответствии с требованиями.
Легко кодировать
Синтаксис Python прост для понимания и программирования. Любой разработчик может понять синтаксис Python за несколько часов. Python можно охарактеризовать как «удобный для программистов»
Расширяемый
При необходимости пользователь также может написать часть кода Python на языке C. Также можно поместить код Python в исходный код на разных языках, например C ++. Это делает Python расширяемым языком.
Важные точки
Обратите внимание на следующие важные моменты, связанные с языком программирования Python:
Он включает в себя методы функционального и структурного программирования, а также методы объектно-ориентированного программирования.
Его можно использовать как язык сценариев или как язык программирования.
Он включает автоматический сбор мусора.
Он включает динамические типы данных высокого уровня и поддерживает различные проверки динамических типов.
Python включает функцию интеграции с C, C ++ и такими языками, как Java.
Как загрузить язык Python в вашу систему?
Чтобы загрузить язык Python в вашу систему, перейдите по этой ссылке -
https://www.python.org/downloads/Он включает пакеты для различных операционных систем, таких как Windows, MacOS и Linux.
Важные инструменты в Python
В этом разделе мы вкратце узнаем о нескольких важных инструментах Python.
Строки Python
Основное объявление строк выглядит следующим образом:
str = 'Hello World!'
Списки Python
Списки python могут быть объявлены как составные типы данных, разделенные запятыми и заключенные в квадратные скобки ([]).
list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']
Кортежи Python
Кортеж - это динамический тип данных Python, который состоит из числа значений, разделенных запятыми. Кортежи заключаются в круглые скобки.
tinytuple = (123, 'john')
Словарь Python
Словарь Python - это разновидность хеш-таблицы. Ключ словаря может быть практически любым типом данных Python. Типами данных обычно являются числа или строки.
tinydict = {'name': 'omkar','code':6734, 'dept': 'sales'}
Что составляет шаблон проектирования в Python?
Python помогает в создании шаблона проектирования с использованием следующих параметров:
- Название шаблона
- Intent
- Aliases
- Motivation
- Problem
- Solution
- Structure
- Participants
- Constraints
- Образец кода
Контроллер представления модели - наиболее часто используемый шаблон проектирования. Разработчикам легко реализовать этот шаблон проектирования.
Ниже приведена базовая архитектура контроллера представления модели.
Давайте теперь посмотрим, как работает структура.
Модель
Он состоит из чистой логики приложения, которое взаимодействует с базой данных. Он включает всю информацию для представления данных конечному пользователю.
Посмотреть
Представление представляет файлы HTML, которые взаимодействуют с конечным пользователем. Он представляет данные модели пользователю.
Контроллер
Он действует как посредник между представлением и моделью. Он прослушивает события, инициированные представлением и моделью запросов.
Код Python
Давайте рассмотрим базовый объект под названием «Человек» и создадим шаблон проектирования 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-страницы.
Вывод
Объяснение
Код python включает логику тегов html, в которых указано значение. Конечный пользователь может просмотреть HTML-файл, созданный кодом Python.
Шаблон Builder - это уникальный шаблон проектирования, который помогает создавать сложные объекты с использованием простых объектов и использует алгоритмический подход. Этот шаблон проектирования относится к категории шаблонов создания. В этом шаблоне проектирования класс строителя строит конечный объект в пошаговой процедуре. Этот строитель не зависит от других объектов.
Преимущества шаблона Builder
Он обеспечивает четкое разделение и уникальный уровень между построением и представлением указанного объекта, созданного классом.
Это позволяет лучше контролировать процесс построения созданного узора.
Это идеальный сценарий для изменения внутреннего представления объектов.
Как реализовать шаблон строителя?
В этом разделе мы узнаем, как реализовать шаблон строителя.
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)
Вывод
Вышеупомянутая программа генерирует следующий вывод -
Объяснение
В выходных данных реализованы все команды и ключевые слова, перечисленные на языке Python. Он печатает необходимые значения переменных.
Шаблон адаптера работает как мост между двумя несовместимыми интерфейсами. Этот тип шаблона проектирования относится к структурному шаблону, поскольку он сочетает в себе возможности двух независимых интерфейсов.
Этот шаблон включает в себя один класс, который отвечает за объединение функций независимых или несовместимых интерфейсов. Примером из реальной жизни может быть кардридер, который действует как адаптер между картой памяти и ноутбуком. Вы вставляете карту памяти в устройство чтения карт, а устройство чтения карт в ноутбук, чтобы карту памяти можно было прочитать через ноутбук.
Шаблон проектирования адаптера помогает работать классам вместе. Он преобразует интерфейс класса в другой интерфейс в зависимости от требований. Шаблон включает в себя видообразование полиморфизм, который называет одно имя и несколько форм. Скажем, для класса формы, который можно использовать в соответствии с собранными требованиями.
Есть два типа шаблона адаптера -
Шаблон адаптера объекта
Этот шаблон проектирования основан на реализации объекта. Следовательно, он называется шаблоном адаптера объекта.
Шаблон адаптера класса
Это альтернативный способ реализации шаблона проектирования адаптера. Паттерн может быть реализован с использованием множественного наследования.
Как реализовать выкройку адаптера?
Давайте теперь посмотрим, как реализовать шаблон адаптера.
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()
Вывод
Вышеупомянутая программа генерирует следующий вывод -
Объяснение
Код включает интерфейс адаптера с различными параметрами и атрибутами. Он включает Adaptee вместе с интерфейсом Target, который реализует все атрибуты и отображает вывод как видимый.
Шаблон декоратора позволяет пользователю добавлять новые функции к существующему объекту без изменения его структуры. Этот тип шаблона проектирования входит в состав структурного шаблона, поскольку этот шаблон действует как оболочка для существующего класса.
Этот шаблон создает класс-декоратор, который обертывает исходный класс и предоставляет дополнительные функции, сохраняя неизменной сигнатуру методов класса.
Мотив шаблона декоратора - динамически прикреплять дополнительные обязанности к объекту.
Как реализовать шаблон проектирования декоратора
Приведенный ниже код является простой демонстрацией того, как реализовать шаблон проектирования декоратора в Python. Иллюстрация подразумевает демонстрацию кофейни в формате урока. Созданный класс coffee является абстрактным, что означает, что его нельзя создать.
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()
Вывод
Вышеупомянутая программа генерирует следующий вывод -
Объяснение
Этот код создает шаблон для приготовления еды. Здесь каждый параметр представляет атрибут для создания части еды, такой как чай, пицца и т. Д.
Выходные данные представляют собой визуализацию атрибутов.
Паттерб наилегчайшего веса относится к категории структурных шаблонов проектирования. Это дает возможность уменьшить количество объектов. Он включает в себя различные функции, которые помогают улучшить структуру приложения. Самая важная особенность объектов-легковесов - неизменность. Это означает, что они не могут быть изменены после постройки. Шаблон использует 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))
Вывод
Вышеупомянутая программа генерирует следующий вывод
Объяснение
Код включает атрибуты класса и экземпляра, которые печатаются в соответствии с требованиями вывода. Есть различные функции, которые составляют часть объектно-ориентированного шаблона. Эти функции описаны в следующей главе.
В этой главе мы сосредоточимся на шаблонах с использованием объектно-ориентированных концепций и их реализации на Python. Когда мы разрабатываем наши программы на основе блоков операторов, которые управляют данными функций, это называется процедурно-ориентированным программированием. В объектно-ориентированном программировании есть два основных экземпляра, называемых классами и объектами.
Как реализовать классы и объектные переменные?
Реализация классов и объектных переменных выглядит следующим образом:
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()
Вывод
Вышеупомянутая программа генерирует следующий вывод -
Объяснение
Эта иллюстрация помогает продемонстрировать природу переменных класса и объекта.
«Население» относится к классу «роботов». Следовательно, он упоминается как переменная или объект класса.
Здесь мы называем переменную класса населения как Robot.population, а не self.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")
Вывод
Вышеупомянутая программа генерирует следующий вывод -
Если вы сосредоточитесь на шаблоне, ряд Фибоначчи будет напечатан с шаблоном итератора. При принудительном завершении пользователя печатается следующий вывод:
Объяснение
Этот код python следует шаблону итератора. Здесь для запуска счета используются операторы приращения. Счетчик заканчивается при принудительном завершении пользователем.
Словари - это структуры данных, которые включают комбинацию значений ключа. Они широко используются вместо JSON - JavaScript Object Notation. Словари используются для программирования API (Application Programming Interface). Словарь сопоставляет набор объектов с другим набором объектов. Словари изменчивы; это означает, что они могут быть изменены по мере необходимости в соответствии с требованиями.
Как реализовать словари в Python?
Следующая программа показывает базовую реализацию словарей на 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])
Вывод
Вышеупомянутая программа генерирует следующий вывод -
Встроенные функции списков Python следующие:
Append()- Добавляет элемент в конец списка.
Extend()- Добавляет элементы списка в другой список.
Insert()- Вставляет элемент в определенный индекс.
Remove()- Удаляет элемент из указанного списка.
Reverse()- Он меняет местами элементы в списке.
sort() - Это помогает отсортировать элементы в хронологическом порядке.
Набор можно определить как неупорядоченную коллекцию, которая является повторяемой, изменяемой, и в нее не включаются повторяющиеся элементы. В Python класс набора - это обозначение математического набора. Основное преимущество использования набора состоит в том, что он включает высокооптимизированный метод проверки конкретного элемента.
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
Вывод
Вышеупомянутая программа генерирует следующий вывод -
Сериализация строк - это процесс записи состояния объекта в поток байтов. В Python библиотека «pickle» используется для включения сериализации. Этот модуль включает мощный алгоритм сериализации и десериализации структуры объекта Python. «Обработка» - это процесс преобразования иерархии объектов Python в поток байтов, а «выделение» - это обратная процедура.
Демонстрация модуля 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)
Вывод
Вышеупомянутая программа генерирует следующий вывод -
Объяснение
«Multiprocessing» - это пакет, аналогичный модулю многопоточности. Этот пакет поддерживает локальный и удаленный параллелизм. Благодаря этому модулю программисты получают возможность использовать несколько процессов в данной системе.
Анти-шаблоны следуют стратегии, противоположной предопределенным шаблонам проектирования. Стратегия включает общие подходы к общим проблемам, которые можно формализовать и в целом рассматривать как хорошую практику разработки. Обычно антипаттерны противоположны и нежелательны. Антишаблоны - это определенные шаблоны, используемые при разработке программного обеспечения, которые считаются плохой практикой программирования.
Важные особенности антипаттернов
Давайте теперь посмотрим на несколько важных особенностей антипаттернов.
Правильность
Эти шаблоны буквально ломают ваш код и заставляют делать неправильные поступки. Ниже приводится простая иллюстрация этого -
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.
Обработка исключений также является основным критерием шаблонов проектирования. Исключение - это ошибка, возникающая во время выполнения программы. Когда возникает конкретная ошибка, важно создать исключение. Это помогает предотвратить сбои программы.
Зачем нужны исключения?
Исключения - это удобные способы обработки ошибок и особых условий в программе. Когда пользователь думает, что указанный код может вызвать ошибку, важно использовать обработку исключений.
Пример - деление на ноль
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