Python Design Patterns 简明教程

Python Design Patterns - Quick Guide

Python Design Patterns - Introduction

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

Design patterns are used to represent the pattern used by developers to create software or web application. These patterns are selected based on the requirement analysis. The patterns describe the solution to the problem, when and where to apply the solution and the consequences of the implementation.

Structure of a design pattern

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

The documentation of design pattern is maintained in a way that focuses more on the technology that is used and in what ways. The following diagram explains the basic structure of design pattern documentation.

design pattern

Pattern Name

简短有效地描述了该模式。

It describes the pattern in short and effective manner.

Intent/Motive

描述了该模式的作用。

It describes what the pattern does.

Applicability

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

It describes the list of situations where pattern is applicable.

Participants and consequences

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

Participants include classes and objects that participate in the design pattern with a list of consequences that exist with the pattern.

Why Python?

Python 是一种开源脚本语言。它拥有支持各种设计模式的库。Python 的语法易于理解并使用英语关键字。

Python is an open source scripting language. It has libraries that support a variety of design patterns. The syntax of python is easy to understand and uses English keywords.

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

Python provides support for the list of design patterns that are mentioned below. These design patterns will be used throughout this tutorial −

  1. Model View Controller Pattern

  2. Singleton pattern

  3. Factory pattern

  4. Builder Pattern

  5. Prototype Pattern

  6. Facade Pattern

  7. Command Pattern

  8. Adapter Pattern

  9. Prototype Pattern

  10. Decorator Pattern

  11. Proxy Pattern

  12. Chain of Responsibility Pattern

  13. Observer Pattern

  14. State Pattern

  15. Strategy Pattern

  16. Template Pattern

  17. Flyweight Pattern

  18. Abstract Factory Pattern

  19. Object Oriented Pattern

Benefits of using design pattern

以下是设计模式的不同优点 -

Following are the different benefits of design pattern −

  1. Patterns provide developer a selection of tried and tested solutions for the specified problems.

  2. All design patterns are language neutral.

  3. Patterns help to achieve communication and maintain well documentation.

  4. It includes a record of accomplishment to reduce any technical risk to the project.

  5. Design patterns are highly flexible to use and easy to understand.

Python Design Patterns - Gist

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

Python is an open source scripting language, which is high-level, interpreted, interactive and object-oriented. It is designed to be highly readable. The syntax of Python language is easy to understand and uses English keywords frequently.

Features of Python Language

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

In this section, we will learn about the different features of Python language.

Interpreted

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

Python is processed at runtime using the interpreter. There is no need to compile program before execution. It is similar to PERL and PHP.

Object-Oriented

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

Python follows object-oriented style and design patterns. It includes class definition with various features like encapsulation, polymorphism and many more.

Portable

以 Windows 操作系统编写的 Python 代码可在 Mac 操作系统中使用。代码可以根据要求进行重复使用并且可移植。

Python code written in Windows operating system and can be used in Mac operating system. The code can be reused and portable as per the requirements.

Easy to code

Python 语法易于理解和编码。任何开发人员都可以在几个小时内理解 Python 的语法。Python 可以被描述为“面向程序员”。

Python syntax is easy to understand and code. Any developer can understand the syntax of Python within few hours. Python can be described as “programmer-friendly”

Extensible

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

If needed, a user can write some of Python code in C language as well. It is also possible to put python code in source code in different languages like C++. This makes Python an extensible language.

Important Points

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

Consider the following important points related to Python programming language −

  1. It includes functional and structured programming methods as well as object-oriented programming methods.

  2. It can be used as scripting language or as a programming language.

  3. It includes automatic garbage collection.

  4. It includes high-level dynamic data types and supports various dynamic type checking.

  5. Python includes a feature of integration with C, C++ and languages like Java.

How to download python language in your system?

要下载系统中的 Python 语言,请访问此链接:

To download Python language in your system, follow this link −

python language

它包括适用于 Windows、MacOS 和 Linux 发行版等多种操作系统的包。

It includes packages for various operating systems like Windows, MacOS and Linux distributions.

The Important Tools in Python

在本节中,我们将简要了解 Python 中的一些重要工具。

In this section, we will learn in brief about a few important tools in Python.

Python Strings

字符串的基本声明如下:

The basic declaration of strings is as follows −

str = 'Hello World!'

Python Lists

Python 列表可以声明为用逗号分隔并用方括号([])括起来的复合数据类型。

The lists of python can be declared as compound data types separated by commas and enclosed within square brackets ([]).

list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']

Python Tuples

元组是 Python 的动态数据类型,由用逗号分隔的多个值组成。元组用括号括起来。

A tuple is dynamic data type of Python, which consists of number of values separated by commas. Tuples are enclosed with parentheses.

tinytuple = (123, 'john')

Python Dictionary

Python 字典是一种哈希表。字典键可以是 Python 的几乎任何数据类型,数据类型通常是数字或字符串。

Python dictionary is a type of hash table. A dictionary key can be almost any data type of Python. The data types are usually numbers or strings.

tinydict = {'name': 'omkar','code':6734, 'dept': 'sales'}

What constitutes a design pattern in Python?

Python 有助于使用以下参数构成设计模式:

Python helps in constituting a design pattern using the following parameters −

  1. Pattern Name

  2. Intent

  3. Aliases

  4. Motivation

  5. Problem

  6. Solution

  7. Structure

  8. Participants

  9. Constraints

  10. Sample Code

Model View Controller Pattern

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

Model View Controller is the most commonly used design pattern. Developers find it easy to implement this design pattern.

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

Following is a basic architecture of the Model View Controller −

architecture

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

Let us now see how the structure works.

Model

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

It consists of pure application logic, which interacts with the database. It includes all the information to represent data to the end user.

View

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

View represents the HTML files, which interact with the end user. It represents the model’s data to user.

Controller

它充当视图和模型之间的一个中介者。它监听由视图触发的事件并向模型查询相同内容。

It acts as an intermediary between view and model. It listens to the events triggered by view and queries model for the same.

Python code

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

Let us consider a basic object called “Person” and create an MVC design pattern.

Model.py

Model.py

import json

class Person(object):
   def __init__(self, first_name = None, last_name = None):
      self.first_name = first_name
      self.last_name = last_name
   #returns Person name, ex: John Doe
   def name(self):
      return ("%s %s" % (self.first_name,self.last_name))

   @classmethod
   #returns all people inside db.txt as list of Person objects
   def getAll(self):
      database = open('db.txt', 'r')
      result = []
      json_list = json.loads(database.read())
      for item in json_list:
         item = json.loads(item)
         person = Person(item['first_name'], item['last_name'])
         result.append(person)
      return result

它调用一个方法,该方法获取数据库中“人”表的全部记录。记录以 JSON 格式表示。

It calls for a method, which fetches all the records of the Person table in database. The records are presented in JSON format.

View

它显示模型中获取的所有记录。视图从不与模型交互;控制器完成这项工作(与模型和视图通信)。

It displays all the records fetched within the model. View never interacts with model; controller does this work (communicating with model and view).

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!'

Controller

控制器通过 getAll() 方法与模型交互,该方法获取显示给最终用户的所有记录。

Controller interacts with model through the getAll() method which fetches all the records displayed to the end user.

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 Design Patterns - Singleton

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

This pattern restricts the instantiation of a class to one object. It is a type of creational pattern and involves only one class to create methods and specified objects.

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

It provides a global point of access to the instance created.

singleton pattern

How to implement a singleton class?

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

The following program demonstrates the implementation of singleton class where it prints the instances created multiple times.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

implementation of singleton

创建的实例数量是相同的,并且输出中列出的对象没有差异。

The number of instances created are same and there is no difference in the objects listed in output.

Python Design Patterns - Factory

工厂模式属于创建模式列表类别。它提供了创建对象的一种最佳方法。在工厂模式中,通过不向客户端公开逻辑并将新创建的对象称为公共接口,来创建对象。

The factory pattern comes under the creational patterns list category. It provides one of the best ways to create an object. In factory pattern, objects are created without exposing the logic to client and referring to the newly created object using a common interface.

在 Python 中使用工厂方法来实现工厂模式。当用户调用一个方法以便我们传入一个字符串,并且返回值作为通过工厂方法实现的新对象时。在工厂方法中使用的对象类型由通过方法传递的字符串决定。

Factory patterns are implemented in Python using factory method. When a user calls a method such that we pass in a string and the return value as a new object is implemented through factory method. The type of object used in factory method is determined by string which is passed through method.

在下面的示例中,每个方法都包含作为参数的对象,它是通过工厂方法实现的。

In the example below, every method includes object as a parameter, which is implemented through factory method.

How to implement a factory pattern?

现在让我们看看如何实现工厂模式。

Let us now see how to implement a factory pattern.

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 页面的创建。

The button class helps to create the html tags and the associated html page. The client will not have access to the logic of code and the output represents the creation of html page.

Output

factory pattern

Explanation

python 代码包括 HTML 标记的逻辑,该逻辑指定值。最终用户可以查看由 Python 代码创建的 HTML 文件。

The python code includes the logic of html tags, which specified value. The end user can have a look on the HTML file created by the Python code.

Python Design Patterns - Builder

Builder 模式是一种独特的观察模式,它有助于使用简单的对象构建复杂的对象并使用算法方法。该设计模式属于创建模式类别。在此设计模式中,生成器类分步构建最终对象。该生成器独立于其他对象。

Builder Pattern is a unique design pattern which helps in building complex object using simple objects and uses an algorithmic approach. This design pattern comes under the category of creational pattern. In this design pattern, a builder class builds the final object in step-by-step procedure. This builder is independent of other objects.

Advantages of Builder Pattern

  1. It provides clear separation and a unique layer between construction and representation of a specified object created by class.

  2. It provides better control over construction process of the pattern created.

  3. It gives the perfect scenario to change the internal representation of objects.

How to implement builder pattern?

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

In this section, we will learn how to implement the 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()

Output

上述程序生成以下输出 −

The above program generates the following output −

builder pattern

Python Design Patterns - Prototype

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

Prototype design pattern helps to hide the complexity of the instances created by the class. The concept of the existing object will differ with that of the new object, which is created from scratch.

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

The newly copied object may have some changes in the properties if required. This approach saves time and resources that go in for the development of a product.

How to implement a prototype pattern?

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

Let us now see how to implement a prototype pattern.

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

Output

上面的程序将生成以下输出 −

The above program will generate the following output −

prototype pattern

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

The output helps in creating new objects with the existing ones and it is clearly visible in the output mentioned above.

Python Design Patterns - Facade

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

Facade design pattern provides a unified interface to a set of interfaces in a subsystem. It defines a higher-level interface that any subsystem can use.

门面类知道哪个子系统对请求负责。

A facade class knows which subsystem is responsible for a request.

How to design a facade pattern?

让我们现在看看如何设计门面模式。

Let us now see how to design a facade pattern.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

facade pattern

Explanation

该程序是针对一个场景进行设计的。它负责启动汽车或任何驾驶车辆的引擎。如果你观察代码,它还包括与之关联的驾驶、停车和消耗燃料等功能。

This program is designed with a scenario. It is that of starting the engine of a car or any driving vehicle. If you observe the code, it includes the associated functions to drive, to park and to consume fuel as well.

Python Design Patterns - Command

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

Command Pattern adds a level of abstraction between actions and includes an object, which invokes these actions.

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

In this design pattern, client creates a command object that includes a list of commands to be executed. The command object created implements a specific interface.

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

Following is the basic architecture of the command pattern −

architecture of command pattern

How to implement the command pattern?

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

We will now see how to implement the design pattern.

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)

Output

上述程序生成以下输出 −

The above program generates the following output −

command pattern

Explanation

该输出实现了 Python 语言中列出的所有命令和关键字。它打印变量的必要值。

The output implements all the commands and keywords listed in Python language. It prints the necessary values of the variables.

Python Design Patterns - Adapter

适配器模式充当两个不兼容接口之间的桥梁。此类设计模式属于结构模式,因为此模式结合了两个独立接口的功能。

Adapter pattern works as a bridge between two incompatible interfaces. This type of design pattern comes under structural pattern as this pattern combines the capability of two independent interfaces.

该模式涉及单个类,该类负责合并独立或不兼容接口的功能。真实生活中的一个例子是读卡器,它充当存储卡和笔记本电脑之间的适配器。你将存储卡插入读卡器,再将读卡器插入笔记本电脑,这样就可以通过笔记本电脑读取存储卡了。

This pattern involves a single class, which is responsible to join functionalities of independent or incompatible interfaces. A real life example could be the case of a card reader, which acts as an adapter between memory card and a laptop. You plug in the memory card into the card reader and the card reader into the laptop so that memory card can be read via the laptop.

适配器设计模式有助于让类协同工作。它将类的接口转换为基于需求的另一个接口。该模式包含一项命名为一个名称和多个形式的多态性规范。例如用于形状的类,它可以根据收集到的需求使用。

The adapter design pattern helps to work classes together. It converts the interface of a class into another interface based on requirement. The pattern includes a speciation a polymorphism which names one name and multiple forms. Say for a shape class which can use as per the requirements gathered.

有两种类型的适配器模式−

There are two types of adapter pattern −

Object Adapter Pattern

该设计模式依赖于对象实现。因此,它被称为对象适配器模式。

This design pattern relies on object implementation. Hence, it is called the Object Adapter Pattern.

Class Adapter Pattern

这是一个实现适配器设计模式的备选方式。可以使用多重继承实现该模式。

This is an alternative way to implement the adapter design pattern. The pattern can be implemented using multiple inheritances.

How to implement the adapter pattern?

让我们现在看看如何实现适配器模式。

Let us now see how to implement the 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()

Output

上述程序生成以下输出 −

The above program generates the following output −

adapter pattern

Explanation

该代码包括带有各种参数和属性的适配器接口。它包括具有目标接口的被适配类,该接口实现所有属性并显示输出以供查看。

The code includes adapter interface with various parameters and attributes. It includes Adaptee along with Target interface that implements all the attributes and displays the output as visible.

Python Design Patterns - Decorator

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

Decorator pattern allows a user to add new functionality to an existing object without altering its structure. This type of design pattern comes under structural pattern as this pattern acts as a wrapper to existing class.

这个模式创建一个装饰器类,该类包装原始类并提供附加功能,同时保持类方法签名不变。

This pattern creates a decorator class, which wraps the original class and provides additional functionality keeping the class methods signature intact.

装饰器模式的目的是为一个对象动态添加附加责任。

The motive of a decorator pattern is to attach additional responsibilities of an object dynamically.

How to implement decorator design pattern

下面提到的代码是一个简单的演示,说明如何在 Python 中实现装饰器设计模式。说明涉及以类的格式演示一家咖啡店。创建的咖啡类是一个抽象类,这意味着它不能被实例化。

The code mentioned below is a simple demonstration of how to implement decorator design pattern in Python. The illustration involves demonstration of a coffee shop in the format of class. The coffee class created is an abstract, which means that it cannot be instantiated.

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'

咖啡店的抽象类的实现是通过一个单独的文件完成的,如下所示−

The implementation of the abstract class of the coffee shop is done with a separate file as mentioned below −

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

Output

上述程序生成以下输出 −

The above program generates the following output −

decorator pattern

Python Design Patterns - Proxy

代理设计模式包括一个新对象,该对象代替现有的称为“真实主题”的对象,称为“代理”。创建真实主题的代理对象必须在同一个界面中,以至于客户端不应该有任何想法,即代理用于代替真实对象。客户端向代理发出的请求将通过真实主题传递。

The proxy design pattern includes a new object, which is called “Proxy” in place of an existing object which is called the “Real Subject”. The proxy object created of the real subject must be on the same interface in such a way that the client should not get any idea that proxy is used in place of the real object. Requests generated by the client to the proxy are passed through the real subject.

代理模式的 UML 表示如下 -

The UML representation of proxy pattern is as follows −

proxy pattern

How to implement the proxy pattern?

现在让我们看看如何实现代理模式。

Let us now see how to implement the proxy pattern.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

proxy pattern output

代理模式设计有助于复制我们创建的图像。 display_image() 函数有助于检查值是否在命令提示符中打印。

The proxy pattern design helps in replicating the images that we created. The display_image() function helps to check if the values are getting printed in the command prompt.

Chain of Responsibility

责任链模式用于在软件中实现松耦合,其中客户端的指定请求通过其中的对象链传递。它有助于构建对象链。请求从一端进入,从一个对象移动到另一个对象。

The chain of responsibility pattern is used to achieve loose coupling in software where a specified request from the client is passed through a chain of objects included in it. It helps in building a chain of objects. The request enters from one end and moves from one object to another.

此模式允许对象发送命令,而不了解哪个对象将处理请求。

This pattern allows an object to send a command without knowing which object will handle the request.

How to implement the chain of responsibility pattern?

现在我们将看到如何实现责任链模式。

We will now see how to implement the chain of responsibility pattern.

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)

Output

上述程序生成以下输出 −

The above program generates the following output −

design chain pattern

Explanation

上面的代码为每月任务创建了一个报告,其中它通过每个函数发送命令。它需要两个处理程序 - 用于 PDF 和文本。一旦所需对象执行每个函数,它便会打印输。

The above code creates a report for monthly tasks where it sends commands through each function. It takes two handlers – for PDF and for text. It prints the output once the required object executes each function.

Python Design Patterns - Observer

在此模式中,对象表示为等待事件触发的观察程序。一旦发生指定事件,观察程序将附加到主题上。当事件发生时,主题会告诉观察程序已经发生。

In this pattern, objects are represented as observers that wait for an event to trigger. An observer attaches to the subject once the specified event occurs. As the event occurs, the subject tells the observers that it has occurred.

以下 UML 图表示观察程序模式 -

The following UML diagram represents the observer pattern −

observer pattern

How to implement the observer pattern?

现在让我们看看如何实现观察者模式。

Let us now see how to implement the observer pattern.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

observer pattern output

Explanation

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

The above code explains the procedure of downloading a particular result. As per the observer pattern logic, every object is treated as observer. It prints the output when event is triggered.

Python Design Patterns - State

它提供了一个状态机模块,该模块使用从指定状态机类派生的子类实现。这些方法与状态无关,并导致使用修饰符声明的转换。

It provides a module for state machines, which are implemented using subclasses, derived from a specified state machine class. The methods are state independent and cause transitions declared using decorators.

How to implement the state pattern?

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

The basic implementation of state pattern is shown below −

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)

Output

上述程序生成以下输出 −

The above program generates the following output −

design pattern output

Python Design Patterns - Strategy

策略模式是一种行为模式。策略模式的主要目标是使客户端能够从不同的算法或过程选择以完成指定的任务。可以在没有任何并发症的情况下为指定的任务换入和换出不同的算法。

The strategy pattern is a type of behavioral pattern. The main goal of strategy pattern is to enable client to choose from different algorithms or procedures to complete the specified task. Different algorithms can be swapped in and out without any complications for the mentioned task.

当访问外部资源时,可以使用此模式提高灵活性。

This pattern can be used to improve flexibility when external resources are accessed.

How to implement the strategy pattern?

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

The program shown below helps in implementing the strategy pattern.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

strategy pattern

Explanation

它从函数提供策略列表,这些函数执行输出。此行为模式的主要重点是行为。

It provides a list of strategies from the functions, which execute the output. The major focus of this behavior pattern is behavior.

Python Design Patterns - Template

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

A template pattern defines a basic algorithm in a base class using abstract operation where subclasses override the concrete behavior. The template pattern keeps the outline of algorithm in a separate method. This method is referred as the template method.

以下是模板模式的不同特点 −

Following are the different features of the template pattern −

  1. It defines the skeleton of algorithm in an operation

  2. It includes subclasses, which redefine certain steps of an algorithm.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

template pattern

Explanation

这个代码创建了一个用于准备餐点的模板。这里,每个参数表示创建膳食部分的属性,如茶、比萨等。

This code creates a template to prepare meal. Here, each parameter represents the attribute to create a part of meal like tea, pizza, etc.

输出显示了属性的可视化。

The output represents the visualization of attributes.

Python Design Patterns - Flyweight

享元模式属于结构设计模式类别。它提供了一种减少对象数量的方法。它包括有助于改进应用程序结构的各种功能。享元对象最重要的特点是不变的。这意味着创建后它们不能被修改。该模式使用 HashMap 来存储引用对象。

The flyweight patterb comes under the structural design patterns category. It provides a way to decrease object count. It includes various features that help in improving application structure. The most important feature of the flyweight objects is immutable. This means that they cannot be modified once constructed. The pattern uses a HashMap to store reference objects.

How to implement the flyweight pattern?

以下程序有助于实现享元模式 −

The following program helps in implementing the flyweight pattern −

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

Output

上述程序生成以下输出 −

The above program generates the following output −

flyweight pattern

Python Design Patterns - Abstract Factory

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

The abstract factory pattern is also called factory of factories. This design pattern comes under the creational design pattern category. It provides one of the best ways to create an object.

它包括一个负责创建与工厂相关的对象的接口。

It includes an interface, which is responsible for creating objects related to Factory.

How to implement the abstract factory pattern?

下面的程序有助于实现抽象工厂模式。

The following program helps in implementing the abstract factory pattern.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

abstract factory pattern

Explanation

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

In the above program, the abstract factory creates objects for each window. It calls for each method, which executes the output as expected.

Python Design Patterns - Object Oriented

面向对象模式是最常用的模式。几乎每个编程语言中都可以找到这个模式。

The object oriented pattern is the most commonly used pattern. This pattern can be found in almost every programming language.

How to implement the object oriented pattern?

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

Let us now see how to implement the object oriented pattern.

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

Output

上面的程序生成了以下输出

The above program generates the following output

object oriented

Explanation

该代码包含类属性和实例属性,它们根据输出要求进行打印。形成面向对象模式一部分的特征有很多。这些特征将在下一章节中进行解释。

The code includes class attribute and instance attributes, which are printed as per the requirement of the output. There are various features that form part of the object oriented pattern. The features are explained in the next chapter.

Object Oriented Concepts Implementation

在本章中,我们将重点关注使用面向对象概念的模式及其在 Python 中的实现。当我们围绕语句块设计我们的程序时,这些语句块围绕函数处理数据,这称为过程化编程。在面向对象编程中,有两个称为类和对象的主实例。

In this chapter, we will focus on patterns using object oriented concepts and its implementation in Python. When we design our programs around blocks of statements, which manipulate the data around functions, it is called procedure-oriented programming. In object-oriented programming, there are two main instances called classes and objects.

How to implement classes and object variables?

类和对象变量的实现如下 −

The implementation of classes and object variables are as follows −

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

Output

上述程序生成以下输出 −

The above program generates the following output −

object oriented concepts implementation

Explanation

此说明有助于演示类和对象变量的性质。

This illustration helps to demonstrate the nature of class and object variables.

  1. “population” belongs to the “Robot” class. Hence, it is referred to as a class variable or object.

  2. Here, we refer to the population class variable as Robot.population and not as self.population.

Python Design Patterns - Iterator

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

The iterator design pattern falls under the behavioral design patterns category. Developers come across the iterator pattern in almost every programming language. This pattern is used in such a way that it helps to access the elements of a collection (class) in sequential manner without understanding the underlying layer design.

How to implement the iterator pattern?

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

We will now see how to implement the iterator pattern.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

iterator

如果您关注该模式,将使用迭代器模式打印斐波纳契数列。在用户强制结束时,将打印以下输出 -

If you focus on the pattern, Fibonacci series is printed with the iterator pattern. On forceful termination of user, the following output is printed −

fibonacci series

Explanation

此 Python 代码遵循迭代器模式。此处,递增运算符用于启动计数。计数在用户强制结束时结束。

This python code follows the iterator pattern. Here, the increment operators are used to start the count. The count ends on forceful termination by the user.

Python Design Patterns - Dictionaries

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

Dictionaries are the data structures, which include a key value combination. These are widely used in place of JSON – JavaScript Object Notation. Dictionaries are used for API (Application Programming Interface) programming. A dictionary maps a set of objects to another set of objects. Dictionaries are mutable; this means they can be changed as and when needed based on the requirements.

How to implement dictionaries in Python?

以下程序展示了 Python 中字典的基本实现,从创建到实现。

The following program shows the basic implementation of dictionaries in Python starting from its creation to its implementation.

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

Output

上述程序生成以下输出 −

The above program generates the following output −

dictionaries

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

*Note −*There are drawbacks related to the implementation of dictionaries in Python.

Drawback

字典不支持字符串,元组和列表等顺序数据类型的顺序操作。它们属于内置映射类型。

Dictionaries do not support the sequence operation of the sequence data types like strings, tuples and lists. These belong to the built-in mapping type.

Lists Data Structure

Lists 数据结构是 Python 中一个通用的数据类型,它可以写成方括号中逗号分隔的值列表。

The Lists data structure is a versatile datatype in Python, which can be written as a list of comma separated values between square brackets.

Syntax

以下是结构的基本语法 -

Here is the basic syntax for the structure −

List_name = [ elements ];

如果您观察,语法声明为数组,唯一区别在于列表可以包含不同数据类型元素。数组包含相同数据类型的元素。列表可以包含字符串、整数和对象的组合。列表可用于堆栈和队列的实现。

If you observe, the syntax is declared like arrays with the only difference that lists can include elements with different data types. The arrays include elements of the same data type. A list can contain a combination of strings, integers and objects. Lists can be used for the implementation of stacks and queues.

列表是可变的。这些可以根据需要随时更改。

Lists are mutable. These can be changed as and when needed.

How to implement lists?

以下程序显示了列表的实现 -

The following program shows the implementations of lists −

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

Output

上述程序生成以下输出 −

The above program generates the following output −

list data structure

Python 列表的内置函数如下 -

The built-in functions of Python lists are as follows −

  1. Append()− It adds element to the end of list.

  2. Extend()− It adds elements of the list to another list.

  3. Insert()− It inserts an item to the defined index.

  4. Remove()− It deletes the element from the specified list.

  5. Reverse()− It reverses the elements in list.

  6. sort() − It helps to sort elements in chronological order.

Python Design Patterns - Sets

集合可以定义为可迭代、可变且不包含重复元素的无序集合。在 Python 中,集合类是数学集合的表示形式。使用集合的主要优点是它包括检查特定元素的高度优化方法。

A set can be defined as unordered collection that is iterable, mutable and there is no inclusion of duplicate elements in it. In Python, set class is a notation of mathematical set. The main advantage of using a set is that it includes highly optimized method for checking specific element.

Python 包含一个称为冻结集合的单独类别。这些集合是不可变对象,只支持产生所需结果的方法和运算符。

Python includes a separate category called frozen sets. These sets are immutable objects that only support methods and operators that produce a required result.

How to implement sets?

以下程序有助于实现集合 −

The following program helps in the implementation of sets −

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

Output

上述程序生成以下输出 −

The above program generates the following output −

sets

冻结集合可以使用以下程序进行演示 −

The frozen set can be demonstrated using the following program −

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)

Output

上述程序生成以下输出 −

The above program generates the following output −

frozen set

Python Design Patterns - Queues

队列是一组对象,它定义一个遵循 FIFO(快速进先出)和 LIFO(后进先出)程序的简单数据结构。插入和删除操作分别称为 enqueuedequeue 操作。

Queue is a collection of objects, which define a simple data structure following the FIFO (Fast In Fast Out) and the LIFO (Last In First Out) procedures. The insert and delete operations are referred as enqueue and dequeue operations.

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

Queues do not allow random access to the objects they contain.

How to implement the FIFO procedure?

以下程序有助于实现 FIFO−

The following program helps in the implementation of 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()

Output

上述程序生成以下输出 −

The above program generates the following output −

fifo

How to implement the LIFO procedure?

以下程序有助于实现 LIFO 程序−

The following program helps in the implementation of the LIFO procedure −

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

Output

上述程序生成以下输出 −

The above program generates the following output −

lifo

What is a Priority Queue?

优先级队列是一种容器数据结构,其管理一组具有已排序键的记录,以快速访问指定数据结构中键值最小或最大的记录。

Priority queue is a container data structure that manages a set of records with the ordered keys to provide quick access to the record with smallest or largest key in specified data structure.

How to implement a priority queue?

优先级队列的实现如下−

The implementation of priority queue is as follows −

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

Output

上述程序生成以下输出 −

The above program generates the following output −

priority queues

Strings and Serialization

字符串序列化是将对象的状态写入字节流的过程。在 Python 中,“pickle”库用于启用序列化。该模块包括用于序列化和反序列化 Python 对象结构的强大算法。“酸洗”是将 Python 对象层次结构转换为字节流的过程,“去酸洗”是相反的过程。

String serialization is the process of writing a state of object into a byte stream. In python, the “pickle” library is used for enabling serialization. This module includes a powerful algorithm for serializing and de-serializing a Python object structure. “Pickling” is the process of converting Python object hierarchy into byte stream and “unpickling” is the reverse procedure.

pickle 模块的演示如下−

The demonstration of the pickle module is as follows −

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)

Output

上述程序生成以下输出 −

The above program generates the following output −

serialization

Concurrency in Python

并发经常被误解为并行。并发意味着以系统化的方式计划执行独立的代码。本章重点介绍使用 Python 为操作系统执行并发性。

Concurrency is often misunderstood as parallelism. Concurrency implies scheduling independent code to be executed in a systematic manner. This chapter focuses on the execution of concurrency for an operating system using Python.

以下程序有助于为操作系统执行并发性−

The following program helps in the execution of concurrency for an operating system −

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)

Output

上述程序生成以下输出 −

The above program generates the following output −

concurrency

Explanation

“multiprocessing”是一个类似于 threading 模块的包。该包支持本地和远程并发。由于该模块,程序员可以利用给定系统上的多个进程。

“multiprocessing” is a package similar to the threading module. This package supports local and remote concurrency. Due to this module, programmers get the advantage to use multiple processes on the given system.

Python Design Patterns - Anti

反模式遵循与预定义设计模式相反的策略。该策略包括针对常见问题的常见方法,这些方法可以被形式化,并且通常可以被认为是一种良好的开发实践。通常,反模式是相反的和不受欢迎的。反模式是软件开发中使用的某些模式,被认为是不好的编程实践。

Anti-patterns follow a strategy in opposition to predefined design patterns. The strategy includes common approaches to common problems, which can be formalized and can be generally considered as a good development practice. Usually, anti-patterns are opposite and undesirable. Anti- patterns are certain patterns used in software development, which are considered as bad programming practices.

Important features of anti-patterns

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

Let us now see a few important features of anti-patterns.

Correctness

这些模式从根本上破坏了你的代码,让你做错事。以下对此有一个简单的说明−

These patterns literally break your code and make you do wrong things. Following is a simple illustration of this −

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

Maintainability

如果一个程序易于理解和修改以满足要求,则称该程序是可维护的。导入模块可以被认为是可维护性的一个例子。

A program is said to be maintainable if it is easy to understand and modify as per the requirement. Importing module can be considered as an example of maintainability.

import math
x = math.ceil(y)
# or
import multiprocessing as mp
pool = mp.pool(8)

Example of anti-pattern

以下示例有助于演示反模式 −

Following example helps in the demonstration of anti-patterns −

#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

Explanation

该示例包括展示在 Python 中创建函数的良好和不良标准。

The example includes the demonstration of good and bad standards for creating a function in Python.

Python Design Patterns - Exception Handling

处理异常也是设计模式的一个主要标准。异常是在程序执行过程中发生的错误。当发生特定错误时,生成一个异常非常重要。这有助于减少程序崩溃。

Handling exceptions is also a primary criterion of design patterns. An exception is an error that happens during the execution of a program. When a particular error occurs, it is important to generate an exception. This helps in curbing program crashes.

Why use exceptions?

异常是处理程序中错误和特殊情况的便捷方式。当用户认为指定的代码可能产生错误时,使用异常处理非常重要。

Exceptions are convenient ways of handling errors and special conditions in a program. When a user thinks that the specified code can produce an error then it is important to use exception handling.

Example – Division by zero

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)

Output

上述程序生成以下输出 −

The above program generates the following output −

exceptions

Raising Exceptions

在 Python 编程中,特别是当运行时发生相应的代码错误时,会引发异常。这可以用 “raise” 关键字强制引发。

In Python programming specifically, exceptions are raised when corresponding error of code occurs at run time. This can be forcefully raised using the “raise” keyword.

Syntax

   raise KeyboardInterrupt
Traceback (most recent call last):
...
KeyboardInterrupt