Python-design-patterns-quick-guide

提供:Dev Guides
移動先:案内検索

Pythonデザインパターン-はじめに

デザインパターンは、ソフトウェアまたはWebアプリケーションを作成するために開発者が使用するパターンを表すために使用されます。 これらのパターンは、要件分析に基づいて選択されます。 パターンは、問題の解決策、解決策を適用するタイミングと場所、および実装の結果を記述します。

設計パターンの構造

設計パターンの文書化は、使用されているテクノロジーとその方法により重点を置いた方法で維持されます。 次の図は、設計パターン文書の基本構造を説明しています。

デザインパターン

パターン名

パターンを短く効果的な方法で説明します。

意図/動機

パターンの機能を説明します。

適用範囲

パターンが適用される状況のリストについて説明します。

参加者と結果

参加者には、デザインパターンに参加するクラスとオブジェクトが含まれ、パターンとともに存在する結果のリストが含まれます。

なぜPythonなのか

Pythonはオープンソースのスクリプト言語です。 さまざまなデザインパターンをサポートするライブラリがあります。 pythonの構文は理解しやすく、英語のキーワードを使用します。

Pythonは、以下で説明する設計パターンのリストのサポートを提供します。 これらの設計パターンは、このチュートリアル全体で使用されます-

  • モデルビューコントローラーパターン
  • シングルトンパターン
  • 工場パターン
  • ビルダーパターン
  • プロトタイプパターン
  • ファサードパターン
  • コマンドパターン
  • アダプターパターン
  • プロトタイプパターン
  • デコレータパターン
  • プロキシパターン
  • 責任の連鎖パターン
  • オブザーバーパターン
  • 状態パターン
  • 戦略パターン
  • テンプレートパターン
  • フライウェイトパターン
  • 抽象ファクトリーパターン
  • オブジェクト指向パターン

デザインパターンを使用する利点

以下は、設計パターンのさまざまな利点です-

  • パターンは、指定された問題に対して、開発者に試行済みのテスト済みソリューションの選択肢を提供します。
  • すべてのデザインパターンは言語に依存しません。
  • パターンは、コミュニケーションを実現し、適切なドキュメントを維持するのに役立ちます。
  • プロジェクトの技術的リスクを軽減するための達成記録が含まれています。
  • 設計パターンは非常に柔軟に使用でき、理解しやすいものです。

Pythonデザインパターン-要点

Pythonはオープンソースのスクリプト言語であり、高レベルで、解釈され、インタラクティブで、オブジェクト指向です。 読みやすいように設計されています。 Python言語の構文は理解しやすく、英語のキーワードを頻繁に使用します。

Python言語の機能

このセクションでは、Python言語のさまざまな機能について学習します。

解釈済み

Pythonは、実行時にインタープリターを使用して処理されます。 実行前にプログラムをコンパイルする必要はありません。 これは、PERLおよびPHPに似ています。

オブジェクト指向

Pythonは、オブジェクト指向のスタイルとデザインパターンに従います。 カプセル化、ポリモーフィズムなどのさまざまな機能を備えたクラス定義が含まれています。

ポータブル

Windowsオペレーティングシステムで記述されたPythonコード。Macオペレーティングシステムで使用できます。 コードは、要件に従って再利用および移植できます。

コーディングが簡単

Python構文は理解しやすく、コーディングも簡単です。 開発者なら誰でも、数時間以内にPythonの構文を理解できます。 Pythonは「プログラマーフレンドリー」と表現できます。

拡張可能

必要に応じて、ユーザーはPythonコードの一部をC言語で書くこともできます。 C ++などのさまざまな言語のソースコードにPythonコードを配置することもできます。 これにより、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は、次のパラメータを使用して設計パターンを構成するのに役立ちます-

  • パターン名
  • 意図
  • エイリアス
  • 動機
  • 問題
  • 溶液
  • 構造
  • 参加者
  • 制約
  • サンプルコード

モデルビューコントローラーパターン

Model View Controllerは、最も一般的に使用される設計パターンです。 開発者は、この設計パターンを簡単に実装できます。

以下は、Model View Controllerの基本的なアーキテクチャです-

アーキテクチャ

構造がどのように機能するかを見てみましょう。

モデル

データベースと対話する純粋なアプリケーションロジックで構成されます。 エンドユーザーにデータを表すためのすべての情報が含まれています。

View

ビューは、エンドユーザーと対話するHTMLファイルを表します。 ユーザーに対するモデルのデータを表します。

コントローラ

ビューとモデルの間の媒介として機能します。 ビューによってトリガーされるイベントをリッスンし、同じモデルを照会します。

Pythonコード

「Person」という基本的なオブジェクトを考えて、MVCデザインパターンを作成してみましょう。

*Model.py*
import json

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

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

データベース内のPersonテーブルのすべてのレコードを取得するメソッドを呼び出します。 レコードはJSON形式で表示されます。

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

コントローラ

コントローラーは、エンドユーザーに表示されるすべてのレコードを取得する* 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デザインパターン-シングルトン

このパターンは、クラスのインスタンス化を1つのオブジェクトに制限します。 これは作成パターンの一種であり、1つのクラスのみがメソッドと指定されたオブジェクトを作成します。

作成されたインスタンスへのグローバルアクセスポイントを提供します。

シングルトンパターン

シングルトンクラスを実装する方法

次のプログラムは、複数回作成されたインスタンスを出力するシングルトンクラスの実装を示しています。

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デザインパターン-工場

ファクトリパターンは、作成パターンリストカテゴリに分類されます。 オブジェクトを作成する最良の方法の1つを提供します。 ファクトリパターンでは、クライアントにロジックを公開せずに、共通インターフェイスを使用して新しく作成されたオブジェクトを参照せずにオブジェクトが作成されます。

ファクトリパターンは、ファクトリメソッドを使用してPythonで実装されます。 ユーザーがメソッドを呼び出し、ストリングを渡し、新しいオブジェクトとしての戻り値がファクトリーメソッドを介して実装されるようにします。 ファクトリメソッドで使用されるオブジェクトのタイプは、メソッドを介して渡される文字列によって決定されます。

以下の例では、すべてのメソッドにパラメーターとしてオブジェクトが含まれています。これはファクトリーメソッドを通じて実装されます。

ファクトリパターンを実装する方法

ファクトリパターンを実装する方法を見てみましょう。

class Button(object):
   html = ""
   def get_html(self):
      return selfl

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デザインパターン-ビルダー

Builderパターンは、単純なオブジェクトを使用して複雑なオブジェクトを構築するのに役立ち、アルゴリズムのアプローチを使用するユニークなデザインパターンです。 このデザインパターンは、作成パターンのカテゴリに分類されます。 この設計パターンでは、ビルダークラスが段階的な手順で最終オブジェクトを構築します。 このビルダーは、他のオブジェクトから独立しています。

Builderパターンの利点

  • クラスによって作成された指定されたオブジェクトの構築と表現の間の明確な分離とユニークなレイヤーを提供します。
  • 作成されたパターンの構築プロセスをより適切に制御できます。
  • オブジェクトの内部表現を変更する完璧なシナリオを提供します。

ビルダーパターンの実装方法

このセクションでは、ビルダーパターンを実装する方法を学習します。

class Director:
   __builder = None

   def setBuilder(self, builder):
      self.__builder = builder

   def getCar(self):
      car = Car()

      # First goes the body
      body = self.__builder.getBody()
      car.setBody(body)

      # Then engine
      engine = self.__builder.getEngine()
      car.setEngine(engine)

      # And four wheels
      i = 0
      while i < 4:
         wheel = self.__builder.getWheel()
            car.attachWheel(wheel)
         i += 1
      return car

# The whole product
class Car:
   def __init__(self):
      self.__wheels = list()
      self.__engine = None
      self.__body = None

   def setBody(self, body):
      self.__body = body

   def attachWheel(self, wheel):
      self.__wheels.append(wheel)

   def setEngine(self, engine):
      self.__engine = engine

   def specification(self):
      print "body: %s" % self.__body.shape
      print "engine horsepower: %d" % self.__engine.horsepower
      print "tire size: %d\'" % self.__wheels[0].size

class Builder:
      def getWheel(self): pass
      def getEngine(self): pass
      def getBody(self): pass

class JeepBuilder(Builder):

   def getWheel(self):
      wheel = Wheel()
      wheel.size = 22
      return wheel

   def getEngine(self):
      engine = Engine()
      engine.horsepower = 400
      return engine

   def getBody(self):
      body = Body()
      body.shape = "SUV"
      return body

# Car parts
class Wheel:
   size = None

class Engine:
   horsepower = None

class Body:
   shape = None

def main():
   jeepBuilder = JeepBuilder() # initializing the class

   director = Director()

   # Build Jeep
   print "Jeep"
   director.setBuilder(jeepBuilder)
   jeep = director.getCar()
   jeep.specification()
   print ""

if __name__ == "__main__":
   main()

出力

上記のプログラムは、次の出力を生成します-

ビルダーパターン

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デザインパターン-アダプター

アダプタパターンは、2つの互換性のないインターフェイス間のブリッジとして機能します。 このタイプの設計パターンは、2つの独立したインターフェースの機能を組み合わせた構造パターンの下にあります。

このパターンには、独立または互換性のないインターフェイスの機能を結合する単一のクラスが含まれます。 実際の例としては、メモリカードとラップトップ間のアダプタとして機能するカードリーダーの場合があります。 メモリカードをカードリーダーに差し込み、カードリーダーをラップトップに差し込み、ラップトップ経由でメモリカードを読み取れるようにします。

アダプタ設計パターンは、クラスを一緒に機能させるのに役立ちます。 要件に基づいて、クラスのインターフェイスを別のインターフェイスに変換します。 パターンには、1つの名前と複数のフォームに名前を付けるポリモーフィズムのスペシエーションが含まれます。 収集された要件に従って使用できる形状クラスについて説明します。

アダプタパターンには2つのタイプがあります-

オブジェクトアダプタパターン

この設計パターンは、オブジェクトの実装に依存しています。 したがって、これはオブジェクトアダプタパターンと呼ばれます。

クラスアダプターパターン

これは、アダプター設計パターンを実装する代替方法です。 パターンは、複数の継承を使用して実装できます。

アダプターパターンの実装方法

ここで、アダプターパターンの実装方法を見てみましょう。

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デザインパターン-プロキシ

プロキシ設計パターンには、「Real Subject」と呼ばれる既存のオブジェクトの代わりに「Proxy」と呼ばれる新しいオブジェクトが含まれます。 実際のサブジェクトで作成されたプロキシオブジェクトは、クライアントが実際のオブジェクトの代わりにプロキシが使用されていることを認識しないように、同じインターフェイス上になければなりません。 クライアントがプロキシに生成したリクエストは、実際のサブジェクトを通過します。

プロキシパターンの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用とテキスト用の2つのハンドラーが必要です。 必要なオブジェクトが各機能を実行すると、出力を印刷します。

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デザインパターン-戦略

戦略パターンは、行動パターンの一種です。 戦略パターンの主な目標は、指定されたタスクを完了するために、クライアントがさまざまなアルゴリズムまたは手順から選択できるようにすることです。 言及されたタスクを複雑にすることなく、さまざまなアルゴリズムを交換できます。

このパターンを使用して、外部リソースにアクセスするときの柔軟性を向上させることができます。

戦略パターンの実装方法

以下に示すプログラムは、戦略パターンの実装に役立ちます。

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

出力

上記のプログラムは、次の出力を生成します-

戦略パターン

説明

出力を実行する関数からの戦略のリストを提供します。 この行動パターンの主な焦点は行動です。

Pythonデザインパターン-テンプレート

テンプレートパターンは、サブクラスが具体的な動作をオーバーライドする抽象操作を使用して、基本クラスの基本アルゴリズムを定義します。 テンプレートパターンは、アルゴリズムの概要を別の方法で保持します。 このメソッドは、テンプレートメソッドと呼ばれます。

以下は、テンプレートパターンのさまざまな機能です-

  • 操作のアルゴリズムのスケルトンを定義します
  • アルゴリズムの特定のステップを再定義するサブクラスが含まれます。
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デザインパターン-抽象ファクトリー

抽象ファクトリパターンは、ファクトリファクトリとも呼ばれます。 このデザインパターンは、創造的なデザインパターンのカテゴリに分類されます。 オブジェクトを作成する最良の方法の1つを提供します。

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

出力

上記のプログラムは、次の出力を生成します-

Abstract Factory Pattern

説明

上記のプログラムでは、抽象ファクトリーは各ウィンドウのオブジェクトを作成します。 各メソッドを呼び出し、期待どおりに出力を実行します。

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での実装に焦点を当てます。 関数の周りのデータを操作するステートメントのブロックの周りにプログラムを設計するとき、それは手続き指向プログラミングと呼ばれます。 オブジェクト指向プログラミングでは、クラスとオブジェクトと呼ばれる2つの主なインスタンスがあります。

クラスとオブジェクト変数を実装する方法は?

クラスとオブジェクト変数の実装は次のとおりです-

class Robot:
   population = 0

   def __init__(self, name):
      self.name = name
      print("(Initializing {})".format(self.name))
      Robot.population += 1

   def die(self):
      print("{} is being destroyed!".format(self.name))
      Robot.population -= 1
      if Robot.population == 0:
         print("{} was the last one.".format(self.name))
      else:
         print("There are still {:d} robots working.".format(
            Robot.population))

   def say_hi(self):
      print("Greetings, my masters call me {}.".format(self.name))

   @classmethod
   def how_many(cls):
      print("We have {:d} robots.".format(cls.population))
droid1 = Robot("R2-D2")
droid1.say_hi()
Robot.how_many()

droid2 = Robot("C-3PO")
droid2.say_hi()
Robot.how_many()

print("\nRobots can do some work here.\n")

print("Robots have finished their work. So let's destroy them.")
droid1.die()
droid2.die()

Robot.how_many()

出力

上記のプログラムは、次の出力を生成します-

オブジェクト指向の概念の実装

説明

この図は、クラス変数とオブジェクト変数の性質を示すのに役立ちます。

  • 「人口」は「ロボット」クラスに属します。 したがって、クラス変数またはオブジェクトと呼ばれます。
  • ここでは、母集団変数をself.populationではなくRobot.populationと呼びます。

Pythonデザインパターン-イテレーター

イテレーターの設計パターンは、動作設計パターンのカテゴリーに分類されます。 開発者は、ほぼすべてのプログラミング言語でイテレーターパターンに出会います。 このパターンは、基になるレイヤー設計を理解せずに、コレクション(クラス)の要素に順次アクセスするのに役立つように使用されます。

イテレータパターンの実装方法

イテレータパターンを実装する方法について説明します。

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 Object Notationの代わりに広く使用されています。 辞書はAPI(Application Programming Interface)プログラミングに使用されます。 辞書は、オブジェクトのセットを別のオブジェクトのセットにマップします。 辞書は変更可能です。これは、要件に基づいて必要に応じて変更できることを意味します。

Pythonで辞書を実装する方法は?

次のプログラムは、Pythonの作成から実装までの辞書の基本的な実装を示しています。

# Create a new dictionary
d = dict() # or d = {}

# Add a key - value pairs to dictionary
d['xyz'] = 123
d['abc'] = 345

# print the whole dictionary
print(d)

# print only the keys
print(d.keys())

# print only values
print(d.values())

# iterate over dictionary
for i in d :
   print("%s %d" %(i, d[i]))

# another method of iteration
for index, value in enumerate(d):
   print (index, value , d[value])

# check if key exist 23. Python Data Structure –print('xyz' in d)

# delete the key-value pair
del d['xyz']

# check again
print("xyz" in d)

出力

上記のプログラムは、次の出力を生成します-

辞書

注- Pythonでの辞書の実装に関連する欠点があります。

欠点

辞書は、文字列、タプル、リストなどのシーケンスデータ型のシーケンス操作をサポートしていません。 これらは組み込みマッピングタイプに属します。

リストのデータ構造

Listsデータ構造は、Pythonの汎用データ型であり、角括弧で囲まれたコンマ区切り値のリストとして記述できます。

構文

ここに構造の基本的な構文があります-

List_name = [ elements ];

観察すると、構文は配列のように宣言されますが、リストには異なるデータ型の要素を含めることができるという唯一の違いがあります。 配列には、同じデータ型の要素が含まれます。 リストには、文字列、整数、オブジェクトの組み合わせを含めることができます。 リストは、スタックとキューの実装に使用できます。

リストは変更可能です。 これらは必要に応じて変更できます。

リストを実装する方法は?

次のプログラムは、リストの実装を示しています-

my_list = ['p','r','o','b','e']
# Output: p
print(my_list[0])

# Output: o
print(my_list[2])

# Output: e
print(my_list[4])

# Error! Only integer can be used for indexing
# my_list[4.0]

# Nested List
n_list = ["Happy", [2,0,1,5]]

# Nested indexing

# Output: a
print(n_list[0][1])

# Output: 5
print(n_list[1][3])

出力

上記のプログラムは、次の出力を生成します-

リストデータ構造

Pythonリストの組み込み関数は次のとおりです-

  • Append()-リストの最後に要素を追加します。
  • Extend()-リストの要素を別のリストに追加します。
  • Insert()-定義されたインデックスにアイテムを挿入します。
  • Remove()-指定されたリストから要素を削除します。
  • Reverse()-リスト内の要素を反転します。
  • * sort()*-時系列順に要素をソートするのに役立ちます。

Pythonデザインパターン-セット

セットは、反復可能で、変更可能で、重複する要素が含まれていない、順序付けられていないコレクションとして定義できます。 Pythonでは、セットクラスは数学的なセットの表記法です。 セットを使用する主な利点は、特定の要素をチェックするための高度に最適化された方法が含まれていることです。

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(ラストインファーストアウト)の手順に従って単純なデータ構造を定義します。 挿入および削除操作は、 enqueue および dequeue 操作と呼ばれます。

キューは、含まれるオブジェクトへのランダムアクセスを許可しません。

FIFO手順の実装方法

次のプログラムは、FIFOの実装に役立ちます-

import Queue

q = Queue.Queue()

#put items at the end of the queue
for x in range(4):
   q.put("item-" + str(x))

#remove items from the head of the queue
while not q.empty():
   print q.get()

出力

上記のプログラムは、次の出力を生成します-

Fifo

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

出力

上記のプログラムは、次の出力を生成します-

Lifo

優先度キューとは何ですか?

優先度キューは、指定されたデータ構造内の最小または最大のキーを持つレコードへの迅速なアクセスを提供するために、順序付けられたキーを持つレコードのセットを管理するコンテナデータ構造です。

優先度キューを実装する方法は?

優先度キューの実装は次のとおりです-

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オブジェクト階層をバイトストリームに変換するプロセスで、「Pickling」は逆の手順です。

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)

出力

上記のプログラムは、次の出力を生成します-

同時実行性

説明

「マルチプロセッシング」は、スレッド化モジュールに似たパッケージです。 このパッケージは、ローカルおよびリモートの同時実行性をサポートしています。 このモジュールにより、プログラマーは特定のシステムで複数のプロセスを使用できるという利点が得られます。

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 = filter_for_foo(["bar","foo","faz"])

if res is not None:
   #continue processing
   pass

#Good
def filter_for_foo(l):
   r = [e for e in l if e.find("foo") != -1]
   if not check_some_critical_condition(r):
      raise SomeException("critical condition unmet!")
   return r

try:
   res = filter_for_foo(["bar","foo","faz"])
   #continue processing

except SomeException:
   i = 0
while i < 10:
   do_something()
   #we forget to increment i

説明

この例には、Pythonで関数を作成するための良い標準と悪い標準のデモが含まれています。

Pythonデザインパターン-例外処理

例外の処理も、設計パターンの主要な基準です。 例外は、プログラムの実行中に発生するエラーです。 特定のエラーが発生した場合、例外を生成することが重要です。 これは、プログラムのクラッシュを抑制するのに役立ちます。

なぜ例外を使用するのですか?

例外は、プログラムのエラーや特別な条件を処理する便利な方法です。 指定したコードでエラーが発生する可能性があるとユーザーが考える場合、例外処理を使用することが重要です。

例–ゼロによる除算

import sys

randomList = ['a', 0, 2]

for entry in randomList:
   try:
      print("The entry is", entry)
      r = 1/int(entry)
      break
   except:
      print("Oops!",sys.exc_info()[0],"occured.")
      print("Next entry.")
      print()
print("The reciprocal of",entry,"is",r)

出力

上記のプログラムは、次の出力を生成します-

例外

例外を発生させる

特にPythonプログラミングでは、実行時に対応するコードエラーが発生すると例外が発生します。 これは、*“ raise” *キーワードを使用して強制的に上げることができます。

構文

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