Pythonプロフェッショナルプログラミングを読みました


Pythonの正しい使い方を学ぶべく、こちらを読んでみました。
ちなみに現在は最新のものが販売されていますが、お金の都合でまずは古い版を読みました。(こちらはPython2系で書かれています。)

Pythonの開発環境構築から使い方、チームでの開発方法、環境構築の自動化、パフォーマンス改善など、実務に大いに役立つことが書かれていました。


*構成

  1. Pythonのセットアップ
  2. Flaskを使ったWebアプリケーション作成
  3. チームでの開発環境構築
  4. ドキュメントの書き方
  5. 課題管理方法
  6. 単体テスト
  7. 環境セットアップの自動化
  8. Mercurialでのソースコード管理
  9. JenkinsでのCI
  10. 環境構築とデプロイの自動化
  11. アプリケーションのパフォーマンス改善
  12. Google App Engine
  13. テストの導入方法
  14. Djangoの使い方
  15. Pythonモジュールの紹介


*1. Pythonのセットアップ

仮想環境の作成からpipを使ったモジュールのインストール、開発で使うエディタなど、開発をするために必要なことが一通り載っています。

仮想環境の作成(virtualenv)
$ mkvirtualenv {仮想環境名}

仮想環境の実行
$ workon newenv

仮想環境の一覧
$ workon

仮想環境下のパッケージ確認
$ pip freeze

仮想環境から抜ける
$ deactivate

仮想環境の削除
$ rmvirtualenv {仮想環境名}

  • エディタにVimを使う方法
    ホームディレクトリに「.vimrc」のファイルを配置し、下記設定を記述します。
syntax on
filetype plugin indent on

Pythonパスの確認
$ python
>>> import sys
>>> sys.path

  • IPython
    Tabキーでの補完やpdbを使ったデバッガの連携もすることができます。
$ pip install IPython

  • PyPI (Python Package Index)
    パイピーアイと発音します。Pythonパッケージを共有するリポジトリです。
    Pythonで開発する際にPyPIから必要なパッケージをインストールすることが多々あります。

  • pep8
    Pythonのコーディングスタイルを策定しているガイドラインです。
    コーディングスタイルをチェックしてくれるモジュールをインストールすることができます。
$ pip install pep8

  • pyflakes
    文法のチェックをしてくるモジュールです。
$ pip install pyflakes

  • pdb
    デバッガです。標準モジュールに含まれているのでインストールは不要です。
    ソースコードに下記を埋め込むとプログラムを実行したときに停止し、対話式でデバッグ実行することができます。
import pdb; pdb.set_trace()


*2. Flaskを使ったWebアプリケーション作成

Webアプリケーションの仕組みについて丁寧に書かれているので、Web系の知識がない人でも十分わかる内容になっています。

また、要件定義から設計をして実装をするといった開発の流れについても丁寧に書いてあるので、これから仕事でWebアプリケーションの開発をする人にとっては非常に参考になりそうです。

まず要件から必要な機能を明らかにし、それをもとに画面を明らかにし、画面をつくります。そのあと機能をつくり、画面に機能を埋め込み動作確認をします。
この流れを私は現場で知らないうちに覚えていましたが、丁寧に教えてもらった機会はなかったので改めて参考になりました。

HTMLやCSSもサンプルコードが載っています。
また、バージョン管理システム、Google Docsといった開発に便利なツールについても記載されています。


*3. チームでの開発環境構築

GoogleDocやSkypeなど、複数人で使えるツールの紹介がされています。


*4. ドキュメントの書き方

ドキュメントの作成は正直面倒くさい、という開発者の思いをわかった上で、書きたくなるドキュメントを書く方法が紹介されています。

  • Sphinx
    ドキュメンテーションツールです。これを使うことで、普段使っているエディタでドキュメントを作成することができ、バージョン管理もすることができるようになります。
    記法はreSTで、ファイルをビルドするとHTMLヤPDFに変換することができます。
    ネットワーク構造にすることができるので、用語集や索引なども作成できます。


*5. 課題管理方法

Redmineを使ったチケットの管理方法や、レビューの大切さについて書かれています。
レビューは間違いの訂正をするだけでなく、ノウハウを共有することができます。
レビューでは、確認してもらいたいことを整理する必要があります。

作業手順書には下記項目を書きます。
  • 目的、概要
  • 作業場所
  • 所有時間とタイムスケジュール
  • 担当者
  • 実行ユーザー、権限
  • 実行コマンド
  • 作業に失敗した場合の対処、切り戻し方法
  • リハーサル記録

レビューする際、形式的なチェックは意味がなく、pep8やpyflakesといったツールを使えば簡単に検出することができます。
また、修正要否については重要性とスケジュールのバランスを考慮する必要があります。


*6. 単体テスト

ViewやModelといったコンポーネント設計の方法やテストについて記載されています。

オブジェクトとRDBMSを結びつけるORマッパーは、SQLAlchemyを使われることが一般的なようです。PyramidやFlaskなどフルスタックでないフレームワークは、SQLAlchemyを使う前提で説明されることが多いそうです。
テストの種類やユニットテストの書き方についても説明が載っています。

  • モジュール
    Pythonソースファイルそれぞれのことを指します。

  • パッケージ
    複数のモジュールをまとめたものを指します。
    __init__.pyをもったディレクトリのことです。

mockの使い方
$ pip install mock

戻り値を指定
import mock
m = mock.Mock()
m.something.return_value = 10

例外を発生
m.something.side_effect = Exception('oops')

アサーションの使用
# 特定の引数で呼ばれたことを確認する
m.something.assert_called_with

# 1度だけ呼ばれたことを確認する
m.something.assert_called_once_with

  • patchデコレータ
    モジュール内のクラスや関数をモックに置き換えることができます。
@patch('sample.SomeService')
def test_it(MockSomeService):
    mock = MockSomeService.return_value
    mock.something.return_value = 10
    from sample import Sample
    retult = Sample()
    assert result = 10

擬似リクエストを扱うには、WebTestを使います。
$ pip install webtest
def test_it():
    from webtest import TestApp
    import myproject.app
    
    # テスト対象を準備
    app = TestApp(myproject.app)
    
    # テスト対象を実行
    res = app.get('/')
    assert "Hello" in res

テストしやすい設計にするために、下記を意識します。
  • 単一責任の原則
    1つのオブジェクトは1つの責務を持ちます。
  • 最小インターフェースの原則
  • オープンクローズの原則
    モジュールの修正が他に派生しないようにします。
  • リコロフの置換原則
    親クラスが発生させない例外をサブクラスから発生させたり、親クラスが受け取っていたパラメータをサブクラスが受け取らなかったり、親クラスが返さない戻り値をサブクラスが返したりといったことはしないようにします。


*7. 環境セットアップの自動化

ソースコードのパッケージングや、pipやsetuptools、virtualenvといったセットアップに必要なツール、自動化に必要なツールなどの紹介が書かれています。

pipなどのコマンドで自動的にインストールするには、PyPIに登録するのが手軽な方法なようです。
# PyPIへのパッケージ登録
$ python setup.py register

# PyPIへのアップロード
$ python setup.py sdist bdist_egg upload

環境全体のパッケージバージョンの固定化
$ pip freeze > /home/requirements.txt

新しい環境にパッケージをインストール
$ pip install -E env2 -r requirements.txt


*8. Mercurialでのソースコード管理

現在はGitを使っているので、この章の内容は省きます。


*9. JenkinsでのCI

プログラムを修正するたびにテストを自動実行して、本番環境で動かないといった問題を解決する仕組みです。
Jenkinsのインストールから設定、スケジュール登録などの説明が載っています。


*10. 環境構築とデプロイの自動化

環境構築手順書の書き方、デプロイ方法について書かれています。

  • Fabricによる自動化
    Pythonで作られたコマンドラインツールで、ローカル環境からリモートサーバー上で任意のシェルコマンドを実行させることができます。また、複数のサーバーに対し、同じコマンドを実行させることもできます。
    使うためにはSSH接続設定が必要です。
    このFabricを使ってPythonファイルに処理を書くことで、デプロイやアプリケーションのセットアップを自動化することができます。

Fabricのインストール
$ pip install fabric
$ fab --version


*11. アプリケーションのパフォーマンス改善

CPU使用率が高い場合は、処理を行うプロセス数・スレッド数を増やす、または性能の良いCPUに交換するといった、高負荷への対策について書かれています。

下記のことに念頭を置いて改善を行います。
  • 効果が大きいと予想したものから試す
  • お金と手間と時間のかからないことから試す
  • 対策の前後でパフォーマンスを測定する

実際にサーバーやツールを使ってパフォーマンスを改善する手順が載っています。

  • ApacheBench
    Apacheのツール群に含まれていて、アプリケーションサーバーを起動したあとにabコマンドを実行することで応答時間を計測することができます。
-nオプションでリクエスト回数、-cオプションでコネクション数を指定します。
$ ab -n 1000 -c 100 http://localhost:5000/

  • gunicorn
    Python WSGIアプリケーションのためのHTTPサーバーです。Linuxで動作し、軽量で高速な動作が特徴です。
# インストール
$ pip install -U gunicorn

# アプリケーションを実行
$ gunicorn -w 1 -b 127.0.0.1:5000 guestbook

  • nginx
    エンジンエックスと読みます。Webサーバーのことで、HTTPサーバーやプロキシサーバーの機能を持っています。軽量で高速に動作することが特徴です。
    gunicornで動かしているアプリケーションに対して、nginxからリバースプロキシで応答を返させるようにすることもできます。
# インストール
$ sudo aptitude install nginx
$ nginx -V

# nginxの起動
$ sudo /etc/init.d/nginx start

# nginxの停止
$ sudo /etc/init.d/nginx stop


*12. Google App Engine

PaaSのクラウドサービスで、負荷に応じて自動的にスケールアウトしてくれるので、サーバの増設や監視のコストを削減することができます。
App Engineを実行するための小さな仮想環境のことをインスタンスといい、OSの1プロセスで起動しているWebサーバーのことを指しています。
なので、仮想マシンのようにSSH接続をしたりアプリケーションをインストールすることはできません。
一時的に多くの負荷がかかって短期間で終了するアプリケーションなどに採用されているケースが多くあります。

実際にApp EngineでFlaskアプリケーションを起動する手順が載っています。
App Engineを動かすためには、app.yamlが必要になります。テストやチューニング、課金の削減といったことについても書かれています。


*13. テストの導入方法

テスト設計の作り方などが載っています。
テスト実施にも優先順位をつけることや、時間がないときの対処方法、障害が多すぎるときなど、現場によくありがちな状況を考慮して書かれています。
ちなみに、非機能要件は早めに始めて問題点を早期に発見する必要があります。
  • 機能要件 – システムテスト
    最終的にすべてが過不足なく動作する
  • 非機能要件 – 性能テスト・負荷テスト
    利用者がストレスなく扱える
  • 基本設計 – 結合テスト
    各機能同士の連携ができているか
  • 詳細設計 – 単体テスト
    実装者の想定通りに実装されている


*14. Djangoの使い方

モデルなどといったアーキテクチャや基本概念が書かれています。マイグレーションや便利なデバッガなど、Django特有の機能について紹介されています。


*15. Pythonモジュールの紹介

Pythonにはすぐに使える便利なモジュールが多々あります。
  • deteutil
    日時の計算を簡単に記述できます。
from datetime import datetime, timedelta

now_time = datetime.now()
yesterday = now_time - timedelta(days=1)
  • chardet
    文字コードを判定します。
import chardet
print(chardet.detect(text))


*読み終わった所感

業務で使うことを考慮されていて、すぐに実践できる内容だと感じました。
私は独学でPythonを勉強していたので、基本的な考え方や実装方法などが書かれていて非常に参考になりました。
Pythonに限らずテスト設計やチューニング方法も記載されていたので、これから業務でWebアプリケーションの開発をする人にとっても大変参考になる書籍かと思います。
最近、Python3系に対応している最新版がでたので、次はそちらを読んでみます。


Previous
Next Post »

人気の投稿