Python 设计模式 - 快速指南


Python 设计模式 - 简介

设计模式用于表示开发人员创建软件或 Web 应用程序所使用的模式。这些模式是根据需求分析选择的。这些模式描述了问题的解决方案、何时何地应用该解决方案以及实施的后果。

设计模式的结构

设计模式文档的维护方式更侧重于所使用的技术以及以何种方式使用。下图解释了设计模式文档的基本结构。

设计模式

图案名称

它以简短而有效的方式描述了该模式。

意图/动机

它描述了该模式的作用。

适用性

它描述了模式适用的情况列表。

参与者和后果

参与者包括参与设计模式的类和对象,以及该模式存在的后果列表。

为什么选择Python?

Python 是一种开源脚本语言。它具有支持各种设计模式的库。python的语法很容易理解,并且使用英文关键字。

Python 提供对下面提到的设计模式列表的支持。这些设计模式将在本教程中使用 -

  • 模型视图控制器模式
  • 单例模式
  • 工厂模式
  • 建造者模式
  • 原型模式
  • 立面图案
  • 命令模式
  • 适配器模式
  • 原型模式
  • 装饰模式
  • 代理模式
  • 责任链模式
  • 观察者模式
  • 状态模式
  • 策略模式
  • 模板模式
  • 享元模式
  • 抽象工厂模式
  • 面向对象模式

使用设计模式的好处

以下是设计模式的不同好处 -

  • 模式为开发人员提供了针对指定问题的一系列经过尝试和测试的解决方案。

  • 所有设计模式都是语言中立的。

  • 模式有助于实现沟通并维护良好的文档。

  • 它包括减少项目技术风险的成就记录。

  • 设计模式使用起来非常灵活并且易于理解。

Python 设计模式 - 要点

Python是一种开源脚本语言,具有高级、解释性、交互性和面向对象的特点。它被设计为具有高度可读性。Python语言的语法易于理解,并且经常使用英文关键字。

Python语言的特点

在本节中,我们将了解Python语言的不同特性。

解释

Python 在运行时使用解释器进行处理。执行前无需编译程序。它类似于 PERL 和 PHP。

面向对象

Python 遵循面向对象的风格和设计模式。它包括具有各种功能(如封装、多态性等)的类定义。

便携的

Python代码在Windows操作系统中编写,可以在Mac操作系统中使用。该代码可以根据要求重用和移植。

易于编码

Python 语法易于理解和编码。任何开发人员都可以在几个小时内理解 Python 的语法。Python可谓“程序员友好”

可扩展

如果需要,用户也可以用 C 语言编写一些 Python 代码。也可以将 python 代码放入不同语言(如 C++)的源代码中。这使得 Python 成为一种可扩展的语言。

要点

考虑以下与 Python 编程语言相关的要点 -

  • 它包括函数式和结构化编程方法以及面向对象的编程方法。

  • 它可以用作脚本语言或编程语言。

  • 它包括自动垃圾收集。

  • 它包括高级动态数据类型并支持各种动态类型检查。

  • Python 具有与 C、C++ 和 Java 等语言集成的功能。

如何在您的系统中下载python语言?

要在您的系统中下载 Python 语言,请点击此链接 -

https://www.python.org/downloads/

Python语言

它包括适用于各种操作系统(例如 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 有助于使用以下参数构建设计模式 -

  • 图案名称
  • 意图
  • 别名
  • 动机
  • 问题
  • 解决方案
  • 结构
  • 参加者
  • 约束条件
  • 示例代码

模型视图控制器模式

模型视图控制器是最常用的设计模式。开发人员发现实现这种设计模式很容易。

以下是模型视图控制器的基本架构 -

建筑学

现在让我们看看该结构是如何工作的。

模型

它由与数据库交互的纯应用程序逻辑组成。它包括向最终用户表示数据的所有信息。

看法

视图代表与最终用户交互的 HTML 文件。它向用户代表模型的数据。

控制器

它充当视图和模型之间的中介。它监听视图触发的事件并查询模型。

Python代码

让我们考虑一个名为“Person”的基本对象并创建一个 MVC 设计模式。

模型.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()

Python 设计模式 - 单例

此模式将类的实例化限制为一个对象。它是一种创建模式,仅涉及一个类来创建方法和指定对象。

它提供了对所创建实例的全局访问点。

单例模式

如何实现单例类?

下面的程序演示了单例类的实现,它打印多次创建的实例。

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 设计模式 - 工厂

工厂模式属于创建模式列表类别。它提供了创建对象的最佳方法之一。在工厂模式中,创建对象时无需向客户端公开逻辑并使用通用接口引用新创建的对象。

工厂模式是使用工厂方法在 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标签的逻辑,其中指定了值。最终用户可以查看由 Python 代码创建的 HTML 文件。

Python 设计模式 - 构建器

构建器模式是一种独特的设计模式,它有助于使用简单对象并使用算法方法构建复杂对象。这种设计模式属于创造模式的范畴。在此设计模式中,构建器类逐步构建最终对象。该构建器独立于其他对象。

建造者模式的优点

  • 它在类创建的指定对象的构造和表示之间提供了清晰的分离和独特的层。

  • 它可以更好地控制所创建的模式的构造过程。

  • 它提供了改变对象内部表示的完美场景。

如何实现建造者模式?

在本节中,我们将学习如何实现构建器模式。

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()

输出

上述程序生成以下输出 -

建造者模式

Python 设计模式 - 原型

原型设计模式有助于隐藏类创建的实例的复杂性。现有对象的概念与从头开始创建的新对象的概念不同。

如果需要,新复制的对象的属性可能会有一些变化。这种方法节省了产品开发的时间和资源。

如何实现原型模式?

现在让我们看看如何实现原型模式。

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()

输出

上述程序将生成以下输出 -

原型模式

输出有助于使用现有对象创建新对象,并且在上述输出中清晰可见。

Python 设计模式 - 外观

外观设计模式为子系统中的一组接口提供了统一的接口。它定义了任何子系统都可以使用的更高级别的接口。

外观类知道哪个子系统负责请求。

如何设计立面图案?

现在让我们看看如何设计外观模式。

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()

输出

上述程序生成以下输出 -

立面图案

解释

这个程序是根据场景设计的。这是启动汽车或任何行驶车辆的发动机的过程。如果您观察代码,它还包括驾驶、停车和消耗燃料的相关功能。

Python 设计模式 - 命令

命令模式在操作之间添加了一个抽象级别,并包含一个调用这些操作的对象。

在此设计模式中,客户端创建一个命令对象,其中包含要执行的命令列表。创建的命令对象实现特定的接口。

以下是命令模式的基本架构 -

命令模式的架构

如何实现命令模式?

我们现在将了解如何实现设计模式。

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语言中列出的所有命令和关键字。它打印变量的必要值。

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 设计模式 - 装饰器

装饰器模式允许用户向现有对象添加新功能而不改变其结构。这种类型的设计模式属于结构模式,因为该模式充当现有类的包装器。

此模式创建一个装饰器类,它包装原始类并提供附加功能,保持类方法签名完整。

装饰器模式的动机是动态附加对象的附加职责。

如何实现装饰器设计模式

下面提到的代码是如何在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()))

输出

上述程序生成以下输出 -

装饰模式

Python 设计模式 - 代理

代理设计模式包括一个称为“代理”的新对象来代替称为“真实主体”的现有对象。真实主体创建的代理对象必须位于同一接口上,这样客户端就不会知道代理是用来代替真实对象的。客户端向代理生成的请求通过真实主体传递。

代理模式的 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 和文本。一旦所需的对象执行每个函数,它就会打印输出。

Python 设计模式 - 观察者

在此模式中,对象表示为等待事件触发的观察者。一旦指定的事件发生,观察者就会附着到主体上。当事件发生时,主体告诉观察者它已经发生了。

下面的 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()

输出

上述程序生成以下输出 -

观察者模式输出

解释

上面的代码解释了下载特定结果的过程。根据观察者模式逻辑,每个对象都被视为观察者。当事件被触发时,它会打印输出。

Python 设计模式 - 状态

它为状态机提供了一个模块,该模块使用派生自指定状态机类的子类来实现。这些方法是状态独立的,并导致使用装饰器声明的转换。

状态模式如何实现?

状态模式的基本实现如下所示 -

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)

输出

上述程序生成以下输出 -

设计模式输出

Python 设计模式 - 策略

策略模式是Behave模式的一种。策略模式的主要目标是使客户端能够选择不同的算法或过程来完成指定的任务。可以换入和换出不同的算法,而不会为上述任务带来任何复杂性。

此模式可用于提高访问外部资源时的灵活性。

战略模式如何实施?

下面显示的程序有助于实施策略模式。

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()

输出

上述程序生成以下输出 -

策略模式

解释

它提供了执行输出的函数的策略列表。这种Behave模式的主要焦点是Behave。

Python 设计模式 - 模板

模板模式使用抽象操作在基类中定义基本算法,其中子类覆盖具体Behave。模板模式将算法的轮廓保留在单独的方法中。这种方法称为模板法。

以下是模板模式的不同特征 -

  • 它定义了操作中算法的骨架

  • 它包括子类,这些子类重新定义了算法的某些步骤。

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()

输出

上述程序生成以下输出 -

模板模式

解释

此代码创建一个准备饭菜的模板。这里,每个参数代表创建一部分餐食的属性,如茶、披萨等。

输出表示属性的可视化。

Python 设计模式 - 享元

蝇量级模式属于结构设计模式类别。它提供了一种减少对象数量的方法。它包括有助于改进应用程序结构的各种功能。享元对象最重要的特征是不可变的。这意味着它们一旦构建就无法修改。该模式使用 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()

输出

上述程序生成以下输出 -

享元模式

Python 设计模式 - 抽象工厂

抽象工厂模式也称为工厂的工厂。这种设计模式属于创意设计模式类别。它提供了创建对象的最佳方法之一。

它包含一个接口,负责创建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())

输出

上述程序生成以下输出 -

抽象工厂模式

解释

在上面的程序中,抽象工厂为每个窗口创建对象。它调用每个方法,该方法按预期执行输出。

Python 设计模式 - 面向对象

面向对象模式是最常用的模式。这种模式几乎可以在所有编程语言中找到。

如何实现面向对象模式?

现在让我们看看如何实现面向对象模式。

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。

Python 设计模式 - 迭代器

迭代器设计模式属于Behave设计模式类别。开发人员几乎在每种编程语言中都会遇到迭代器模式。该模式的使用方式有助于以顺序方式访问集合(类)的元素,而无需了解底层设计。

如何实现迭代器模式?

现在我们将了解如何实现迭代器模式。

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 代码遵循迭代器模式。这里,增量运算符用于开始计数。计数在用户强制终止时结束。

Python 设计模式 - 字典

字典是包含键值组合的数据结构。它们广泛用于代替 JSON(JavaScript 对象表示法)。字典用于API(应用程序编程接口)编程。字典将一组对象映射到另一组对象。字典是可变的;这意味着它们可以根据要求随时进行更改。

如何用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)

输出

上述程序生成以下输出 -

词典

注意 - Python 中字典的实现存在一些缺点。

退税

字典不支持字符串、元组、列表等序列数据类型的序列操作。这些属于内置映射类型。

列表数据结构

列表数据结构是 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中,集合类是数学集合的一种表示法。使用集合的主要优点是它包含用于检查特定元素的高度优化的方法。

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)

输出

上述程序生成以下输出 -

冷冻套装

Python 设计模式 - 队列

队列是对象的集合,它定义了遵循 FIFO(快进快出)和 LIFO(后进先出)过程的简单数据结构。插入和删除操作称为入队出队操作。

队列不允许随机访问它们包含的对象。

如何实现先进先出的程序?

以下程序有助于 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 对象结构的强大算法。“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 中的并发

并发经常被误解为并行性。并发意味着安排独立的代码以系统的方式执行。本章重点介绍使用 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”是一个类似于threading模块的包。该包支持本地和远程并发。由于这个模块,程序员可以在给定系统上使用多个进程。

Python 设计模式 - 反

反模式遵循与预定义设计模式相反的策略。该策略包括解决常见问题的通用方法,可以将其形式化并通常被视为良好的开发实践。通常,反模式是相反的并且是不可取的。反模式是软件开发中使用的某些模式,它们被认为是不好的编程实践。

反模式的重要特征

现在让我们看看反模式的一些重要特征。

正确性

这些模式实际上会破坏你的代码并让你做错误的事情。以下是对此的简单说明 -

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 = filte