スクリプト作成からオブジェクト向けPythonプログラミングへ

9529 ワード

たまたまdeveloperWorksで見かけたのですが、pythonでプロシージャ型サーバ管理プログラムを書くのに慣れている私のような初心者に、回って共有してもらったような気がします.
引用する
Pythonの近年の人気が急増しているのは、この言語が非常に柔軟で、機能が非常に強いためだ.Pythonは、システム管理、Web開発、GUIプログラミング、科学計算などに使用できます.本稿の主な目標は,Bash,PHPまたは他の言語を用いてスクリプトプロセスコードを記述することに慣れている人に,オブジェクト向けPython開発を紹介し,オブジェクト向けPython開発に変換することである.Pythonのこのようなますます流行性は、現在他のプログラミング言語を使用している開発者にとって、彼らの最も好きな言語のほかに、Pythonを採用していくつかのプロジェクトを完成することができることを意味しています.
プロセスプログラミングには当然のことながら,ある問題を解決するための高度に有効な方法である可能性がある.非常に基本的な階層では、プロシージャプログラミングは命令のリストとして定義することができ、BashおよびPHPは通常、このような方法で記述される.しかし、Pythonの流行により、Web開発者やシステム管理者であるPHPとBashスクリプト作成者は、オブジェクト向けのプログラミングとPythonを同時に学ばなければならない状況に陥っている.
オブジェクト指向という概念を一度に把握することは難しいので,本稿ではプロセス式BashとPHPスクリプトを採用し,まずそれらをプロセス式Pythonに変換する.最後のステップとして、オブジェクト向けPythonという終了目標に変換されます.本稿では,終了時にオブジェクト向けPythonのいくつかの利点を簡単に議論し,最後にプロセスや関数式プログラミングに適したいくつかの不利なシナリオについて議論する.本稿が終わると,BashやPHPプログラマーは,恐れずにオブジェクト向けPythonプロジェクトに頭を突っ込むことができるはずである.
PHPとBashによるディスク監視関数の記述
PHPは主にブラウザで実行するためですが、exec関数でシステム呼び出しを実行することもできます.PHPで記述された最初の例では、Shellコマンド「df-h」の出力をキャプチャし、出力を配列に配置し、正規表現に基づいて出力の各行をチェックします.ローが正規表現と一致する場合は、ローが印刷されます.この例をホームディレクトリから実行する場合は、indexと名前を付けるだけです.php、Apache/mod_に置きますphpサーバの対外サービスディレクトリにあります.
PHPディスク監視例
<html>
<body>
<?php

//Analyzes disk usage
//Takes regex pattern and message
function disk_space( $pattern="/2[0-9]%/", $message="CAPACITY WARNING:" )

{
    exec(escapeshellcmd("df -h"),$output_lines,$return_value);
    foreach ($output_lines as $output) {
        if (preg_match( $pattern, $output ))
            echo "<b>$message</b> $output <br />";

    }
}

disk_space()

?>
</body>
</html>
ブラウザでこのページを実行すると、次の結果が得られます.
CAPACITY WARNING: /dev/sda1 3.8G 694M 2.9G 20% /
このコードを参照すると、20~29%の行に一致するように正規表現モードが設定されていることがわかります.このモードは、20%が非常に低いディスク容量であるため、他のフラグ、例えば90〜99%に適応するために容易に変更することができる.
次に、Bash関数で同じことをどのようにするかを見てみましょう.Bashでは、システム呼び出しを実際に処理しているため、この問題はより簡単に解決できます.この例では、grepへのパイプの使用が容易になるため、配列や正規表現ライブラリを使用する必要もありません.ただし、Bashで関数のデフォルトパラメータを設定するのは常に面倒です.
Bashディスク監視例
#!/usr/bin/env bash

#function flags disk usage takes pattern and message optionally
function disk_space ()
{
    #checks for pattern parameter
    if [ "$1" != "" ]; then
        pattern=$1
    else
        pattern="2[0-9]%"
    fi

    #checks for message parameter
    if [ "$2" != "" ]; then
        message=$2
    else
        message="CAPACITY WARNING:"
    fi

    #looks at output for pattern to flag
    output_lines=`df -h | grep $pattern`
    if [ "$output_lines" != "" ]; then
        echo $message $output_lines
    fi
}

#example of optional parameters usage
#disk_space 9[0-9]% ALERT:

disk_space
このスクリプトを実行すると、同じ出力が得られるので、出力の表示をスキップできます.このスクリプトのPHPバージョンとBashバージョンから見つけることができる相関は、このプロシージャコードが実際にコマンドのセットのように実行されることです.コンピュータは子供のように見えますが、子供に靴紐を初めて結ぶなど、何かをする方法を教えてくれます.Pythonで「オブジェクト向けモデル」を検討する前に、Pythonを使用して同じスクリプトのプロシージャバージョンを作成する方法を見てみましょう.
Pythonディスク監視例
from subprocess import Popen, PIPE
import re

def disk_space(pattern="2[0-9]%", message="CAPACITY WARNING:"):

        #takes shell command output
        ps = Popen("df -h", shell=True,stdout=PIPE, stderr=PIPE)
        output_lines = ps.stdout.readlines()
        for line in output_lines():
            line = line.strip()
            if re.search(pattern,line):
                print "%s %s" % (message,line)

disk_space()

私たちのコードのプロセスPythonバージョンを見てみると、BashとPHPバージョンとよく似ています.Pythonの場合、サブプロシージャモジュールはShellコマンドのシステム呼び出しを処理し、BashとPHPで配列と呼ばれるリストに出力する.PHPバージョンとよく似ていて、コマンドの標準出力ラインリストの項目を反復しました.検索モードを構成する正規表現を探し、注入された特殊なメッセージを使用してディスクレポート行を印刷します.これは、上から下へのスクリプトの問題をどのように解決するかの古典的な例ですが、次のセクションでは、この方法を完全に変更し、オブジェクトの観点から問題を考慮します.
プロセスからオブジェクト向けPythonへ
プロセスプログラミングは通常、初心者の開発者の最も自然なプログラミングスタイルであり、多くの問題に対しても高度に有効である.一方、抽象を作成して再利用可能なコードを作成するには、オブジェクト向けのプログラミングが非常に有用な方法である可能性があります.しかしながら、プロジェクトがある程度複雑になると、プロセスコードは通常、その根本的な欠陥を露呈する.次に、前の例のオブジェクト向けバージョンに直接進み、どのような変化があるかを見てみましょう.
オブジェクト向けPythonディスク監視スクリプト
#!/usr/bin/env python

from subprocess import Popen, PIPE
import re

class DiskMonitor():
    """Disk Monitoring Class"""
    def __init__(self,
                pattern="2[0-9]%",
                message="CAPACITY WARNING",
                cmd = "df -h"):
        self.pattern = pattern
        self.message = message
        self.cmd = cmd

    def disk_space(self):
        """Disk space capacity flag method"""
        ps = Popen(self.cmd, shell=True,stdout=PIPE,stderr=PIPE)
        output_lines = ps.stdout.readlines()
        for line in output_lines:
            line = line.strip()
            if re.search(self.pattern,line):
                print "%s %s" % (self.message,line)

if __name__ == "__main__":
    d = DiskMonitor()
    d.disk_space()

このコードのオブジェクト向けバージョンを表示すると、コードがより抽象的になることがわかります.抽象化が多すぎると設計の問題になる場合がありますが、この例では、問題をより再利用可能な部分に分離できます.DiskMonitorクラスには__があります.init__ method、新しいパラメータを定義してdisk_space関数は現在、クラスの1つの方法です.
この新しいスタイルを使用すると、元のコードを変更することなく、各セクションを簡単に再利用およびカスタマイズできますが、プロシージャコードを使用する場合は、通常、元のコードを変更する必要があります.オブジェクト向けの設計の1つのより強力で、通常も過度に使用される面は継承である.継承により、新しいクラスで既存のコードを再利用およびカスタマイズできます.次の例では、継承がどのようになるかを見てみましょう.
継承されたオブジェクト向けPythonディスク監視スクリプトの使用
#!/usr/bin/env python

from subprocess import Popen, PIPE
import re

class DiskMonitor():
    """Disk Monitoring Class"""
    def __init__(self,
                pattern="2[0-9]%",
                message="CAPACITY WARNING",
                cmd = "df -h"):
        self.pattern = pattern
        self.message = message
        self.cmd = cmd

    def disk_space(self):
        """Disk space capacity flag method"""
        ps = Popen(self.cmd, shell=True,stdout=PIPE,stderr=PIPE)
        output_lines = ps.stdout.readlines()
        for line in output_lines:
            line = line.strip()
            if re.search(self.pattern,line):
                print "%s %s" % (self.message,line)

class MyDiskMonitor(DiskMonitor):
    """Customized Disk Monitoring Class"""

    def disk_space(self):
        ps = Popen(self.cmd, shell=True,stdout=PIPE,stderr=PIPE)
        print "RAW DISK REPORT:"
        print ps.stdout.read()

if __name__ == "__main__":
    d = MyDiskMonitor()
    d.disk_space()
この継承スクリプトバージョンを実行すると、次の出力が得られます.
RAW DISK REPORT:
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1             3.8G  694M  2.9G  20% /
varrun                252M   48K  252M   1% /var/run
varlock               252M     0  252M   0% /var/lock
udev                  252M   52K  252M   1% /dev
devshm                252M     0  252M   0% /dev/shm

この出力は、上部に注入されたprint文を使用してフィルタされていないdf-hコマンドの結果を印刷するだけなので、前のタグ付きバージョンとは大きく異なります.MyDiskMonitorクラスのメソッドを書き換えることで、disk_を完全に変更できます.spaceメソッドの意図.
他のクラスの属性を再利用できるPython魔法は、この「MyDiskMonitor(DiskMonitor)」文です.新しいクラスの名前を定義するときに、前のクラスの名前をカッコ内に置くだけです.この手順を完了すると、すぐに他のクラスプロパティにアクセスして、自分の望むことをすることができます.しかし、楽しみはそれだけではない.タグメッセージを電子メールで送信する別の方法を追加することで、disk_と命名するかもしれません.alert(self)を使用すると、新しいクラスをさらにカスタマイズできます.これはオブジェクト向けのデザインのすばらしさです.経験のある開発者が作成したコードを再利用し続けることで、多くの時間を節約できます.
残念なことに,オブジェクト向けのプログラミングにも不利な面がある.これらの抽象はすべて複雑さを代価としており,抽象が過度であれば徹底的に巧みに下手になる可能性がある.Pythonは多重継承をサポートするため,抽象はかなり有害な複雑さに達することができる.1つのメソッドを作成するために複数のファイルを表示する場合を想像できますか?信じるかどうかにかかわらず、このような状況は確かに発生し、オブジェクト向けのプログラミングの不幸な現実を代表している.
オブジェクト向けプログラミングの代替案は、関数式プログラミングであり、Pythonは、関数式およびオブジェクト向けおよびプロセス式プログラミングを行うためのリソースを提供する.最後の例では、現在非常に退屈になっているディスク監視コードを関数的に記述する方法について検討します.
関数式のPythonディスク監視スクリプト
from subprocess import Popen, PIPE
import re

def disk_space(pattern="2[0-9]%", message="CAPACITY WARNING:"):
    #Generator Pipeline To Search For Critical Items
    ps = Popen("df -h", shell=True,stdout=PIPE, stderr=PIPE)
    outline = (line.split() for line in ps.stdout)
    flag = (" ".join(row) for row in outline if re.search(pattern, row[-2]))
    for line in flag:
        print "%s %s" % (message,line)

disk_space()

この最後の例を表示すると、本明細書で説明した他のすべてのコードとの違いが非常に大きいです.このコードを行単位で参照する場合は、まず「ps」変数で見たことのない内容から開始できます.次の2行のコードは、ジェネレータ式を使用してファイルオブジェクトps.stdoutを処理し、ファイルを分析し、検索している行を検索します.これらのコード行を切り取ってインタラクティブなPython Shellに貼り付けると、印刷するとサマリーとフラグがジェネレータオブジェクトであることがわかります.ジェネレータオブジェクトには次の方法が付属しているので、パイプで操作を結合できます.
サマリー行は、1行から新しい行文字を除去し、次のジェネレータ式にローを渡します.その後、各行で正規表現の一致を1つずつ検索し、タグに出力を渡します.このようなコンパクトなワークフローは、オブジェクト向けのプログラミングスタイルに取って代わることができ、かなり面白いです.しかしながら、コードの簡潔性は、各行のコードを独立して実行しない限り、デバッグが困難なエラーを引き起こすため、このようなスタイルにも欠点がある.関数プログラミングは、ソリューションをリンクして問題を解決するために頭を悩ませます.これは、プロシージャスタイルから見ても、オブジェクト向けスタイルから見てもかなり異なります.
まとめ
本論文ではBashとPHPからプロセス,オブジェクト指向性について述べ,最後に同じ基本コードを用いた関数式Pythonについて述べたため,実験的性質がある.Pythonは非常に柔軟で機能的な言語であり、他のプログラミング言語の開発者も鑑賞を学ぶことができることを説明したい.Pythonがますます流行するにつれて、他の開発者は第一選択言語のほかに、Pythonを学ぶことも重要になります.
Pythonの最近の2つの最大の発展分野はWeb開発とシステム管理である.Web開発について言えば、PHP開発者はすぐに毎週の選択をしなければならないかもしれません.つまり、どのプロジェクトがPythonを採用したほうが意味があるのか、どのプロジェクトがPHPを採用したほうが意味があるのか.システム管理者、Bash、Perlスクリプトプログラマーの場合、Pythonを使用していくつかのプロジェクトを完了するように要求されることがよくあります.一部はこれが選択されていないためで、一部は多くのサプライヤーが彼らの製品にPython APIを提供しているためです.あなたのツールボックスにPythonを用意して、誰も傷つけません.英語の原文はここにあります.http://www.ibm.com/developerworks/aix/library/au-scripting_to_oo/?S_TACT=105AGX52&S_CMP=content