Python ヒッチハイク・ガイド¶
Python ヒッチハイク・ガイド へようこそ。
これは皆さんの手により生きているガイドです。 貢献したい方は GitHub で fork してください!
この手作りガイドは、初心者と熟練者のPython開発者の両方に、Python のインストール、設定、および使用に関するベスト・プラクティスを日々提供するために存在します。
このガイドは、ほとんど 独断的なもの であり、Python の公式文書では ありません 。 ここでは、すべての Python Webフレームワーク の一覧は見つからないでしょうが、強く推奨されているリストが簡潔に見つかるでしょう。
さあ、始めましょう! まずは、あなたの探しものがどこにあるかを確認しましょう。
Python 入門¶
Python を初めて使いますか? Python 環境を適切にセットアップしましょう。
インタプリタの選択¶
Pythonの状態(3&2)¶
Pythonインタプリタを選択するときには、”Python 2 または Python 3 のどちらを選択する必要がありますか?” という漠然とした質問がありますが、どちらにするかは少々微妙なところです。
状態の基本的な要点は次のとおりです。
- 今日の実稼働アプリケーションの多くは、Python 2.7 を使用しています。
- Python 3は、現時点でアプリケーションの実環境への展開の準備が整っています。
- Python 2.7は、2020年まで必要なセキュリティアップデートのみを受け取ります [6]。
- “Python” というブランドは、Python 3 と Python 2 の両方をカプセル化します。
推奨事項¶
率直に言うと:
- 新しい Python アプリケーションは Python 3 を使用します。
- Python を初めて学ぶなら、Python 2.7 を身近に感じていると思いますが、Python 3 を学ぶことよりも有用ではありません。
- 両方を学ぶ。 どちらも “Python” です。
- 既に構築されているソフトウェアは Python 2.7 に依存していることが多いです。
- 新しいオープンソースの Python ライブラリを作成している場合は、Python 2 と Python 3 の両方を同時に作成することをお勧めします。 新しいライブラリのために Python 3 を広くサポートしたいのは政治的なものであり、多くのユーザを疎外させますが、これは問題ではありません。今後3年間で、少しずつ移り変わることでしょう。
そんなわけで.... 3?¶
使用する Python インタプリタを選択する場合は、最新バージョンの Python 3.x を使用することをお勧めします。これは、すべてのバージョンで新しく改良された標準ライブラリモジュール、セキュリティ、バグ修正がもたらされるからです。
このように、既存のコードベース、Python 2 専用ライブラリ、シンプルさ/馴染みやすさなどの理由がある場合、Python 2 に愛着があり インスピレーションを感じている場合は、Python 2 を使用してもかまいません。 それは害ではありません。
Can I Use Python 3? を実行して、依存しているソフトウェアが Python 3 を採用できるかどうかを確認します。
Python 2.6, 2.7, Python 3 書くことは可能です。 これは、あなたが書いているソフトウェアの種類に応じて、些細なものから難しいものまでさまざまです。 あなたが初心者なら、もっと重要なことが心配されます。
実装¶
人々が Python について話すとき、言語だけ意味するのではなく、CPython の実装も意味することがよくあります。 Python は実際にはさまざまな方法で実装できる言語の仕様です。
CPython¶
CPython は、Cで書かれた Python のリファレンス実装です。Python コードを中間バイトコードにコンパイルし、それを仮想マシンで解釈します。 CPython は、Python パッケージとC拡張モジュールとの最高レベルの互換性を提供します。
オープンソースの Python コードを作成していて、できるだけ広い範囲のユーザーにアプローチしたい場合は、CPython をターゲットにするのが最適です。 Cエクステンションに依存するパッケージを使用するには、CPython が唯一の実装オプションです。
CPython はリファレンス実装であるため、Python 言語のすべてのバージョンはC言語で実装されています。
PyPy¶
PyPy は Python 言語の制限付き静的型サブセットで実装された Python インタプリタです。これは RPython と呼ばれます。 インタプリタにはジャストインタイムコンパイラがあり、複数のバックエンド(C、CLI、JVM)をサポートしています。
PyPyは、パフォーマンスを向上させながら、リファレンス CPython 実装との最大の互換性を目指しています。
Python コードのパフォーマンスを向上させたい場合は、PyPy を試してみる価値があります。 一連のベンチマークでは、現在、CPythonより 5倍以上高速 です。
PyPy は Python 2.7 をサポートします。 ベータ版でリリースされた PyPy3 [1] は、Python 3 をターゲットにしています。
Jython¶
Jython は、Python コードを Java バイトコードにコンパイルし、JVM(Java仮想マシン)によって実行される Python の実装です。さらに、Python モジュールのような Java クラスをインポートして使用することができます。
既存の Java コードベースとのインタフェースが必要な場合や、JVM 用の Python コードを書く必要があるなどの理由がある場合は、Jython が最適です。
Jython は現在 Python 2.7 をサポートしています。 [2]
IronPython¶
IronPython は、.NETフレームワーク用の Python の実装です。これは、Python と .NETフレームワークライブラリの両方を使用することができますし、Python コードを .NETフレームワークの他の言語にも公開することができます。
Python Tools for Visual Studio はIronPythonをVisual Studio開発環境に直接統合し、Windows開発者にとって理想的な選択肢にします。
IronPython は Python 2.7 をサポートしています。 [3]
PythonNet¶
Python for .NET は、ネイティブにインストールされた Python インストールを .NET Common Language Runtime(CLR)にシームレスに統合するパッケージです。 これは IronPython(上記を参照)とは逆のアプローチであり、これは競合するというよりも補完的です。
Pythonnet は、Mono と組み合わせて、OS X や Linux などの Windows 以外のオペレーティングシステム上のネイティブ Python インストールを .NETフレームワーク内で動作させることができます。IronPython に加えて競合することなく実行できます。
Pythonnet は、Python 2.6 から Python 3.5 までをサポートします。 [4] [5]
[1] | http://pypy.org/compat.html |
[2] | https://hg.python.org/jython/file/412a8f9445f7/NEWS |
[3] | http://ironpython.codeplex.com/releases/view/81726 |
[4] | https://travis-ci.org/pythonnet/pythonnet |
[5] | https://ci.appveyor.com/project/TonyRoberts/pythonnet-480xs |
[6] | https://www.python.org/dev/peps/pep-0373/#id2 |
- Properly Install Python
Python を正しくインストールする¶
あなたのオペレーティングシステムに、すでに Python がインストールされている可能性は十分あります。
もしそうなら、あなたは Python を使うために他のものをインストールしたり設定したりする必要はありません。 しかし、実際の使用のために Python アプリケーションを構築する前に、以下のガイドで説明されているツールとライブラリをインストールすることを強くお勧めします。 特に、Setuptools, Pip, Virtualenv は常にインストールする必要があります。他のサードパーティのPython ライブラリを使用する方がはるかに簡単です。
Mac OS X で Python をインストールする¶
注釈
OS X 上に Python 3 をインストールするためのガイド を見てください。
Mac OS X Sierra の最新バージョンには、Python 2.7 が付属しています。
Python を使用するために何か他のものをインストールしたり設定したりする必要はありません。しかし、実際の使用のために Python アプリケーションを構築する前に、次のセクションで説明するツールとライブラリをインストールすることを強くお勧めします。特に、他のサードパーティの Python ライブラリをインストールして管理する方がはるかに簡単なので、Setuptools を常にインストールする必要があります。
OS X に同梱されている Python のバージョンは学習には最適ですが、開発には向いていません。 OS X に同梱されているバージョンは、安定したプロダクションバージョンとされている 現在の Python の公式リリース から古くなっている可能性があります。
正しい方法でやりましょう¶
Python の実際のバージョンをインストールしましょう。
Python をインストールする前に、Cコンパイラをインストールする必要があります。 最も速い方法は
xcode-select --install
を実行して Xcode コマンドラインツールをインストールすることです。 また、Mac App Store または非公式ですが OSX-GCC-Installer パッケージから Xcode の完全版をダウンロードすることもできます。注釈
すでに XCode がインストールされている場合は、OSX-GCC-Installer をインストールしないでください。ソフトウェアを組み合わせることで、診断が困難な問題を引き起こす可能性があります。
注釈
XCode を新規インストールする場合は、ターミナルで
xcode-select --install
を実行してコマンドラインツールを追加する必要があります。OS X には多数の UNIX ユーティリティが付属していますが、Linux システムに精通している人は、欠けている1つの重要なコンポーネント、すなわちまともなパッケージマネージャに気付くでしょう。 Homebrew がこの空白を埋めます。
Homebrew をインストールする には
Terminal
かお気に入りのOSX端末エミュレータを起動して実行してください。$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"スクリプトは、インストールの開始前にどのような変更が行われ、プロンプトを表示するかを説明します。 Homebrew をインストールした後、
PATH
環境変数の先頭に Homebrew ディレクトリを挿入します。これを行うには、~/.profile
ファイルの一番下に次の行を追加します。export PATH=/usr/local/bin:/usr/local/sbin:$PATH
Python 2.7:
$ brew install python
または Python 3 をインストールできます:
$ brew install python3
これには1〜2分かかります。
Setuptools & Pip¶
HomebrewはあなたのためにSetuptoolsと
pip
をインストールします。Setuptools を使うと、単一のコマンド(
easy_install
)を使って、ネットワーク(通常はインターネット)上で互換性のある Python ソフトウェアをダウンロードしてインストールすることができます。 また、このネットワークインストール機能をごくわずかな作業で独自の Python ソフトウェアに追加することもできます。
pip
は簡単に Python パッケージをインストールして管理するためのツールです。これはeasy_install
よりもお勧めです。 これは 多方面において 、easy_install
より優れており、積極的に維持されています。仮想環境¶
仮想環境(一般に ‘virtualenv’ と呼ばれます)は、異なるプロジェクトが必要とする依存関係を別々の場所に保存するためのツールです。 「Project Xはバージョン1.xに依存しますが、Project Yは4.xが必要です」というジレンマを解決し、グローバルなサイトパッケージディレクトリをきれいに管理します。
例えば、Django 1.10を必要とするプロジェクトで作業し、Django 1.8を必要とするプロジェクトを維持することもできます。
詳しくはこちらを参照: Virtual Environments docs。
このページは、別のガイド のリミックス版です。これは、同じライセンスで入手できます。
Windows で Python をインストールする¶
まず、Python 2.7の最新バージョン を公式サイトからダウンロードしてください。完全に最新のバージョンをインストールしたい場合は、Python.orgのWebサイト のホームページからDownloads > Windowsのリンクをクリックしてください。
Windows版はMSIパッケージとして提供されています。 手動でインストールするには、ファイルをダブルクリックしてください。 MSIパッケージ形式により、Windows管理者は標準ツールを使用してインストールを自動化できます。
仕様上、Pythonはバージョン番号が埋め込まれたディレクトリにインストールされます。 Pythonバージョン2.7は
C:\Python27\
にインストールされます。これにより、同じシステム上に複数のバージョンのPythonを競合することなく使用できます。 もちろん、Pythonファイルタイプのデフォルトアプリケーションは、1つのインタプリタだけです。PATH
環境変数も自動的には変更されません。そのため、あなたは常にPythonのコピーが実行されるかどうかを制御することができます。Pythonインタプリタのフルパス名を何度も入力するのはうんざりするので、デフォルトのPythonバージョンのディレクトリを
PATH
に追加してください。 あなたのPythonのインストールがC:\Python27\
にあると仮定して、以下をあなたのPATH
に追加してください:C:\Python27\;C:\Python27\Scripts\
これを簡単に行うには、
powershell
で以下を実行します:[Environment]::SetEnvironmentVariable("Path", "$env:Path;C:\Python27\;C:\Python27\Scripts\", "User")
2番目の (
Scripts
) ディレクトリは、特定のパッケージがインストールされているときにコマンドファイルを受け取りますので、非常に便利です。 Pythonを使用するために何か他のものをインストールしたり設定したりする必要はありません。しかし、実際の使用のためにPythonアプリケーションを構築する前に、次のセクションで説明するツールとライブラリをインストールすることを強くお勧めします。特に、他のサードパーティのPythonライブラリを使う方が非常に簡単なので、Setuptoolsをインストールしてください。Setuptools + Pip¶
最も重要な第三者のPythonソフトウェアはSetutoolsです。これは標準ライブラリのdistutilsによって提供されるパッケージとインストール機能を拡張します。 SetuptoolsをPythonシステムに追加すると、単一のコマンドで対応するPythonソフトウェア製品をダウンロードしてインストールすることができます。 また、このネットワークインストール機能をごくわずかな作業で独自のPythonソフトウェアに追加することもできます。
Windows用のSetuptoolsの最新版を入手するには、ここの利用できるPythonスクリプトを実行してください: ez_setup.py
新しいコマンドを利用できるようになりました: easy_install。 多くの人には推奨されていないと考えられているので、その置き換えをインストールします: pip。 Pipは、パッケージのアンインストールを可能にし、easy_installとは異なり、積極的にメンテナンスされます。
pipをインストールするには、ここの利用できるPythonスクリプトを実行してください: get-pip.py
仮想環境¶
仮想環境は、異なるプロジェクトで必要とされる依存関係を別々の場所に保持するためのツールです。仮想環境は、それらのための仮想的なPython環境を作成することによって実現されます。 「Project Xはバージョン1.xに依存しますが、Project Yは4.xが必要です」というジレンマを解決し、グローバルなサイトパッケージディレクトリをきれいに管理します。
例えば、Django 1.10を必要とするプロジェクトで作業し、Django 1.8を必要とするプロジェクトを維持することもできます。
詳しくはこちらを参照 Virtual Environments docs。
このページは、別のガイド のリミックス版です。これは、同じライセンスで入手できます。
PythonをLinuxにインストールする¶
CentOS、Fedora、Redhat Enterprise(RHEL)、Ubuntu の最新バージョンにはPython 2.7が付属しています。
インストールしたPythonのバージョンを確認するには、コマンドプロンプトを開いて実行してください。
$ python --version
RHELとCentOSの古いバージョンにはPython 2.4が付属していますが、これは現代のPython開発では受け入れられません。 幸いにも、Fedoraの対応物に基づいた高品質の追加パッケージを含む Extra Packages for Enterprise Linux があります。 このリポジトリには、システムのPython 2.4インストールと並行してインストールするように設計されたPython 2.6パッケージが含まれています。
Pythonを使用するために何か他のものをインストールしたり設定したりする必要はありません。 しかし、Pythonアプリケーションを実際に使用して構築する前に、次のセクションで説明するツールとライブラリをインストールすることを強くお勧めします。 特に、他のサードパーティのPythonライブラリを使うのがはるかに簡単になるので、Setuptoolsとpipをインストールする必要があります。
Setuptools & Pip¶
最も重要な2つのサードパーティのPythonパッケージは、 setuptools と pip です。
インストールが完了すると、単一のコマンドで、対応するPythonソフトウェア製品をダウンロード、インストール、アンインストールできます。また、このネットワークインストール機能をごくわずかな作業で独自のPythonソフトウェアに追加することもできます。
Python 2.7.9以降(Python2シリーズ)、Python 3.4以降にはpipがデフォルトで含まれています。
pipがインストールされているかどうかを確認するには、コマンドプロンプトを開き、以下を実行してください。
$ command -v pippipをインストールするには、公式のpipインストールガイド に従ってください。これにより、setuptoolsの最新バージョンが自動的にインストールされます。
仮想環境¶
仮想環境は、異なるプロジェクトで必要とされる依存関係を別々の場所に保持するためのツールです。仮想環境は、それらのための仮想的なPython環境を作成することによって実現されます。 「Project Xはバージョン1.xに依存しますが、Project Yは4.xが必要です」というジレンマを解決し、グローバルなサイトパッケージディレクトリをきれいに管理します。
例えば、Django 1.10を必要とするプロジェクトで作業し、Django 1.8を必要とするプロジェクトを維持することもできます。
詳しくはこちらを参照 Virtual Environments docs。
virtualenvwrapper を使って、仮想環境の管理を容易にすることもできます。
このページは、別のガイド のリミックス版です。これは、同じライセンスで入手できます。
大規模な Python コードを書く¶
本書のこのパートは、Python コードを書くためのベストプラクティスに焦点を当てています。
プロジェクトの構造化¶
「構造」とは、プロジェクトがその目的をどのように最も満たしているかについての決定を意味します。 クリーンで効果的なコードを作成するために、Pythonの機能を最大限に活用する方法を検討する必要があります。 実際には、 “構造”とは、ロジックと依存関係が明確であるクリーンなコードと、ファイルとフォルダがファイルシステムにどのように編成されているかを意味します。
どの機能をどのモジュールに入れる必要がありますか? プロジェクトを通じてデータはどのように流れますか? グループ化して分離できる機能は何ですか? このような質問に答えることで、完成した製品がどのように見えるかを広義で計画し始めることができます。
このセクションでは、Pythonのモジュールとインポートシステムを詳しく見ていきます。プロジェクトの構造を強化するための中心的な要素です。 次に、コードを拡張して確実にテストできるようにするためのさまざまな方法について議論します。
リポジトリの構造¶
構造は重要です。¶
コードスタイル、APIデザイン、オートメーションが健全な開発サイクルに欠かせないのと同様に、リポジトリ構造はプロジェクト アーキテクチャ の重要な部分です。
潜在的なユーザーまたは投稿者があなたのリポジトリのページにアクセスすると、いくつかのことが表示されます。
- プロジェクト名
- プロジェクトの説明
- たくさんのファイル
フォールドの下にスクロールするときだけ、ユーザーはあなたのプロジェクトのREADMEを見ることができます。
あなたのリポジトリが、投げ捨てられた大量のファイルやネストしたディレクトリで混乱している場合、あなたの美しいドキュメントを読む前に他の場所を見るかもしれません。
もちろん、最初の印象はすべてではありません。 あなたとあなたの同僚は、このリポジトリで何時間も過ごし、最終的にはすべての隅々まで親しみを感じるようになります。 そのレイアウトは重要です。
サンプルリポジトリ¶
要約: これは、 Kenneth Reitz が推奨するものです。
このリポジトリは GitHubで利用可能 です。
README.rst
LICENSE
setup.py
requirements.txt
sample/__init__.py
sample/core.py
sample/helpers.py
docs/conf.py
docs/index.rst
tests/test_basic.py
tests/test_advanced.py
いくつかの具体的なことを考えてみましょう。
実際のモジュール¶
Location | ./sample/ or ./sample.py |
Purpose | The code of interest |
あなたのモジュールパッケージはリポジトリの中心です。 遠ざけてはいけません:
./sample/
モジュールが1つのファイルのみで構成されている場合、リポジトリのルートに直接置くことができます:
./sample.py
あなたのライブラリはあいまいなsrcまたはpythonサブディレクトリに属していません。
ライセンス¶
Location | ./LICENSE |
Purpose | Lawyering up. |
おそらくソースコード自体を除いて、リポジトリの最も重要な部分です。 完全なライセンステキストと著作権表示がこのファイルに存在している必要があります。
プロジェクトに使用するライセンスが不明な場合は、 choosealicense.com を参照してください。
もちろん、ライセンスなしでコードを公開することも自由ですが、それによりたくさんの人があなたのコードを使用する可能性を阻んでしまうかもしれません。
Setup.py¶
Location | ./setup.py |
Purpose | Package and distribution management. |
あなたのモジュールパッケージがあなたのリポジトリのルートにある場合、これは明らかにルートにあるはずです。
要件ファイル¶
Location | ./requirements.txt |
Purpose | Development dependencies. |
pip要件ファイル は、リポジトリのルートに置く必要があります。 プロジェクトに貢献するために必要な依存関係、つまりドキュメントのテスト、ビルド、および生成を指定する必要があります。
あなたのプロジェクトに開発の依存関係がない場合や、 setup.py
を介して開発環境を設定したい場合は、このファイルは不要です。
テストスイート¶
Location | ./test_sample.py or ./tests |
Purpose | Package integration and unit tests. |
まず始めに、小さなテストスイートが1つのファイルに存在することがよくあります:
./test_sample.py
テストスイートが成長したら、次のようにテストをディレクトリに移動できます:
tests/test_basic.py
tests/test_advanced.py
明らかに、これらのテストモジュールはパッケージ化されたモジュールをインポートしてテストする必要があります。これにはいくつかの方法があります:
- パッケージが site-packages にインストールされることを期待してください。
- パッケージを適切に解決するために、単純な (しかし 明示的な )パス変更を使用します。
私は後者を強く勧めます。 開発者が積極的に変化するコードベースをテストするために setup.py develop
を実行するように要求するためには、コードベースのインスタンスごとに独立した環境設定が必要です。
個々のテストにインポートコンテキストを与えるには、tests/context.py ファイルを作成します:
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
import sample
次に、個々のテストモジュール内で、次のようにモジュールをインポートします:
from .context import sample
これは、インストール方法に関係なく、常に期待どおりに動作します。
あなた自身のモジュール内でテストを配布すべきだと主張する人もいますが、私は同意しません。 多くの場合、ユーザーの複雑さが増します。 多くのテストスイートでは、ほとんどが追加の依存関係と実行時コンテキストが必要になります。
Makefile¶
Location | ./Makefile |
Purpose | Generic management tasks. |
ほとんどのプロジェクトやPocooプロジェクトを見てみると、Makefileがあることに気付くでしょう。 なぜかというと、これらのプロジェクトはC言語で書かれていません...要するに、makeはプロジェクトの一般的なタスクを定義するために非常に便利なツールであるということです。
Sample Makefile:
init:
pip install -r requirements.txt
test:
py.test tests
.PHONY: init test
リポジトリのルートには、他の一般的な管理スクリプト( manage.py
や fabfile.py
など)も属しています。
Djangoアプリケーションについて¶
私はDjango 1.4のリリース以来、Djangoアプリケーションの新しいトレンドに気付きました。 多くの開発者は、新しいバンドルされたアプリケーションテンプレートのためにリポジトリを構成していません。
どうやって? 彼らはいつも空で新しいリポジトリに行き、以下を実行します:
$ django-admin.py startproject samplesite
結果のリポジトリ構造は次のようになります:
README.rst
samplesite/manage.py
samplesite/samplesite/settings.py
samplesite/samplesite/wsgi.py
samplesite/samplesite/sampleapp/models.py
しかし、このようにしないでください。
反復的なパスは、ツールと開発者の両方にとって混乱を招きます。 不要なネスティングは誰にも役立ちません(モノリシックなSVNリポジトリを懐かしくしていない限り)。
正しくは以下の通りです:
$ django-admin.py startproject samplesite .
“.
” に注意してください。
結果の構造:
README.rst
manage.py
samplesite/settings.py
samplesite/wsgi.py
samplesite/sampleapp/models.py
コードの構造は重要です¶
インポートとモジュールをPythonで処理する方法のおかげで、Pythonプロジェクトを構造化するのは比較的簡単です。 これを簡単に言うと、多くの制約がなく、モデルをインポートするモジュールが把握しやすいということです。 したがって、プロジェクトのさまざまな部分とその相互作用を作成するという、純粋なアーキテクチャ上の任務が残っています。
プロジェクトの簡単な構造化は、それを貧弱にすることも容易であることを意味します。 構造の整っていないプロジェクトのいくつかの兆候は次のとおりです。
- 複数の乱雑な循環依存関係
furn.py
の中のクラスTableとChairがtable.isdoneby()
のような質問に答えるためにworkers.py
からCarpenterをインポートする必要がある場合 逆にCarpenterクラスがTableとChairをインポートする必要がある場合は、carpenter.whatdo()
という質問に答えるためには、循環依存関係があります。 この場合、メソッドや関数の中でimportステートメントを使うなど、脆弱なハックに頼らざるを得ません。
- 非表示のカップリング: 無関係なテストケースで20回のテストが破られるのは、Carpenterのコードを破るためです。変更を適応させるためには非常に慎重な手術が必要です。つまり、Carpenterのコード内のテーブルについての仮定があまりにも多いか、その逆のことです。
- グローバルな状態やコンテキストの大量使用: 明示的に
(height, width, type, wood)
に渡すのではなく、TableとCarpenterは変更可能なグローバル変数に依存しており。 矩形テーブルが正方形になった理由を理解するために、これらのグローバル変数へのすべてのアクセスを精査し、リモートテンプレートコードがこのコンテキストを変更してテーブル次元を混乱させていることを発見する必要があります。
- スパゲッティコード:入れ子にされたif節の複数のページと、多数のコピーペーストされた手続き型コードと適切なセグメンテーションのないループの場合はスパゲッティコードとして知られています。 Pythonの意味のあるインデント(最も論争の的になっている機能の1つ)は、この種のコードを維持することを非常に困難にしています。 良いニュースはあなたがあまりそれを見ないかもしれないということです。
- ラビオリコードは、Pythonの可能性が高いです: それは、何百もの類似した小さなロジック、しばしばクラスまたはオブジェクトで構成され、適切な構造がありません。 FurnitureTable、AssetTableまたはTable、またはTableNewを使用しなければならないことを決して覚えていない場合は、ラビオリコードで泳いでいるかもしれません。
モジュール¶
Pythonモジュールは、利用可能な主要な抽象レイヤーの1つであり、おそらく最も自然なものです。抽象レイヤでは、コードを関連するデータと機能を保持する部分に分けることができます。
たとえば、プロジェクトのレイヤーはユーザーアクションとのインタフェースを処理でき、別のレイヤーはデータの低レベル操作を処理します。 これらの2つの層を分離する最も自然な方法は、1つのファイル内のすべてのインターフェース機能と、別のファイル内のすべての低レベル操作を再グループ化することです。 この場合、インターフェイスファイルは低レベルのファイルをインポートする必要があります。 これは import
と from ... import
文で行います。
import 文を使うとすぐにモジュールを使います。 これらのモジュールは、 os や sys などの組み込みモジュール、環境にインストールしたサードパーティモジュール、プロジェクトの内部モジュールのいずれかです。
スタイルガイドと一致するように、モジュール名は小文字にしておき、ドット (.) や疑問符 (?) などの特別な記号は使用しないでください。 したがって、 my.spam.py
のようなファイル名は避けてください! このように命名すると、Pythonがモジュールを探す方法が妨げられます。
my.spam.py の場合、Pythonは my
という名前のフォルダにある spam.py
ファイルを探します。Pythonドキュメントではドット表記をどのように使うべきかの 例 があります。
モジュール名を my_spam.py
とすることもできますが、私たちの友人でさえ、アンダースコアはモジュール名でよく見られるべきではありません。
いくつかの命名制限の他に、Pythonファイルがモジュールであるために特別なものは必要ありませんが、この概念を適切に使用し、いくつかの問題を避けるためには、インポートメカニズムを理解する必要があります。
具体的には、 import modu
文は適切なファイルを探します。これは、呼び出し側と同じディレクトリに modu.py
がある場合です。見つからなければ、Pythonインタプリタは “path”内の modu.py
を再帰的に検索し、見つからなければImportError例外を送出します。
一旦 modu.py
が見つかると、Pythonインタプリタはモジュールを隔離したスコープで実行します。 そして、 modu.py
内のトップレベルのステートメントが実行されます。 関数とクラスの定義は、モジュールの辞書に格納されています。
次に、モジュールの変数、関数、およびクラスは、Pythonで特に有用で強力なプログラミングの中心概念である、モジュールの名前空間を通じて呼び出し元が利用できるようになります。
多くの言語では、 include file
ディレクティブがプリプロセッサで使用され、ファイル内のすべてのコードを取得し、呼び出し側のコードにコピーします。しかし Pythonではこれが異なります。含まれているコードはモジュールの名前空間で分離されています。これは、一般的に、含まれているコードが望ましくない影響を及ぼすことを心配する必要がないことを意味しているため、既存の関数を同じ名前で上書きします。
import文の特殊な構文を使用すると、より標準的な動作をシミュレートすることができます: from modu import *
。 これは一般に悪い習慣とみなされます。 import *
を 使うと 、コードの読み込みが難しくなり、依存関係をコンパートメント化しにくくなるからです。
from modu import func
は、インポートする関数を特定し、グローバル名前空間に入れる方法です。 グローバルな名前空間にインポートされるものを明示的に示しているので、 import *
よりも害は少ないですが、単純な import modu
より良い唯一の利点は、タイピングを少し省けることです。
とても悪い
[...]
from modu import *
[...]
x = sqrt(4) # Is sqrt part of modu? A builtin? Defined above?
良い
from modu import sqrt
[...]
x = sqrt(4) # sqrt may be part of modu, if not redefined in between
ベスト
import modu
[...]
x = modu.sqrt(4) # sqrt is visibly part of modu's namespace
code_style セクションで述べたように、読みやすさはPythonの主な機能の1つです。読みやすさとは、無用な定型文や混乱を避けることを意味します。したがって、一定のレベルの簡潔さを達成しようと努力しています。しかし、簡潔さとあいまいさは、簡潔さが止まるべき限界です。 modu.func
イディオムのように、クラスや関数がどこから来ているのかをすぐに知ることができるので、最もシンプルな単一ファイルプロジェクトだけでは、コードの読みやすさとわかりやすさが大幅に向上します。
パッケージ¶
Pythonは非常に単純なパッケージシステムを提供しています。これは単純にモジュール機構をディレクトリに拡張したものです。
__init__.py
ファイルを持つディレクトリはPythonパッケージとみなされます。パッケージ内のさまざまなモジュールは、普通のモジュールと同様にインポートされますが、パッケージ全体の定義を集めるために使用される __init__.py
ファイルの特殊な動作を伴います。
ディレクトリ pack/
のファイル modu.py
は、import pack.modu
というステートメントでインポートされます。 この文は __init__.py
ファイルを pack
で探し、すべての最上位レベルの文を実行します。 それから、pack/modu.py
という名前のファイルを探し、すべてのトップレベルのステートメントを実行します。 これらの操作の後で、 modu.py
で定義された変数、関数、またはクラスは、pack.modu名前空間で使用できます。
よく見られる問題は、 __init__.py
ファイルにあまりにも多くのコードを追加することです。 プロジェクトの複雑さが増すと、深いディレクトリ構造にサブパッケージとサブサブパッケージが存在する可能性があります。 この場合、サブサブパッケージから単一の項目をインポートするには、ツリーを走査中に全ての __init__.py
ファイルを実行する必要があります。
パッケージのモジュールとサブパッケージがコードを共有する必要がない場合、 __init__.py
ファイルを空のままにしておくのは正常であり、良い習慣でもあります。
最後に、深くネストされたパッケージをインポートするための便利な構文があります: import very.deep.module as mod
。これにより、 very.deep.module
の冗長な繰り返しの代わりに mod を使うことができます。
オブジェクト指向プログラミング¶
Pythonは、オブジェクト指向プログラミング言語として記述されることがあります。これはやや誤解を招く可能性があり、明確にする必要があります。
Pythonでは、すべてがオブジェクトであり、そのように扱うことができます。これは、たとえば、関数がファーストクラスのオブジェクトであると言うときに意味するものです。関数、クラス、文字列、さらには型はPythonのオブジェクトです。どんなオブジェクトと同様、型を持ち、関数の引数として渡すことができ、メソッドとプロパティを持つことができます。この理解では、Pythonはオブジェクト指向言語です。
しかし、Javaとは異なり、Pythonはオブジェクト指向プログラミングを主なプログラミングパラダイムとして課していません。 Pythonプロジェクトがオブジェクト指向ではないこと、すなわち、クラス定義、クラス継承、またはオブジェクト指向プログラミングに特有の他のメカニズムを使用しないこと、またはごくわずかしか使用しないことは、完全に実行可能です。
さらに、モジュール セクションに見られるように、Pythonがモジュールと名前空間を扱う方法は、開発者に抽象レイヤのカプセル化と分離を保証する自然な方法です。どちらもオブジェクト指向を使用する最も一般的な理由です。 したがって、Pythonプログラマーは、ビジネスモデルで必要とされないときに、オブジェクト指向を使用しないという自由度があります。
不要なオブジェクト指向を避ける理由はいくつかあります。 カスタムクラスを定義することは、いくつかの状態といくつかの機能を結合する場合に便利です。 関数型プログラミングに関する議論で指摘されているように、問題は方程式の “状態” の部分から来ています。
いくつかのアーキテクチャ、通常はWebアプリケーションでは、複数のインスタンスのPythonプロセスが生成され、同時に発生する可能性のある外部要求に応答します。この場合、いくつかの状態をインスタンス化されたオブジェクトに保持することは、世界に関するいくつかの静的情報を保持することを意味し、並行性の問題または競合状態になりがちです。時には、オブジェクトの状態の初期化(通常は __init__()
メソッドで行われます)とそのメソッドの1つによるオブジェクト状態の実際の使用の間に、世界が変更された可能性があります。時代遅れです。例えば、要求はメモリ内のアイテムをロードし、ユーザによってそれを読み取りとしてマークすることができる。別のリクエストで同時にこのアイテムの削除が必要な場合は、最初のプロセスがアイテムをロードした後に実際に削除が行われ、削除されたオブジェクトを読み取り済みとしてマークする必要があります。
これと他の問題は、ステートレス関数の使用がより良いプログラミングパラダイムであるという考えにつながりました。
同じことを言うもう一つの方法は、できるだけ暗黙的なコンテキストと副作用の少ない関数とプロシージャを使用することを提案することです。関数の暗黙のコンテキストは、関数内からアクセスされる永続化層のグローバル変数または項目のいずれかで構成されます。副作用とは、関数がその暗黙のコンテキストに対して行う変更です。関数がグローバル変数または永続化層にデータを保存または削除する場合、それは副作用を伴うと言われています。
文脈や副作用を伴う関数をロジックを持つ関数(純関数と呼ぶ)から慎重に分離することで、次のような利点が得られます。
- 純粋な関数は確定的です: 固定された入力が与えられると、出力は常に同じになります。
- リファクタリングや最適化が必要な場合は、純関数を簡単に変更または置換することができます。
- 純粋な関数は単体テストでテストする方が簡単です。後で複雑なコンテキストの設定やデータのクリーニングが不要になります。
- 純粋な関数は、操作、飾り付け、渡しが簡単です。
要約すると、純粋な関数は、コンテキストや副作用がないため、クラスやオブジェクトよりも効率的なビルディングブロックです。
明らかに、オブジェクト指向は、有用であり、多くの場合必要になります。例えば、操作されるもの (window, buttons, avatars, vehicles) がコンピュータのメモリ内で比較的長い寿命を有するグラフィカルデスクトップアプリケーションまたはゲームを開発する場合などです。
デコレータ¶
Python言語は、’デコレータ’と呼ばれている、シンプルで強力な構文を提供しています。デコレータは、関数またはメソッドをラップする(またはデコレートする)関数またはクラスです。 「デコレートされた」機能または方法は、元の「デコレートされていない」機能または方法を置き換えます。関数はPythonのファーストクラスのオブジェクトであるため、これは ‘手動で’行うことができますが、@デコレータの構文を使用する方が明確であり、したがって好ましいものです。
def foo():
# do something
def decorator(func):
# manipulate func
return func
foo = decorator(foo) # Manually decorate
@decorator
def bar():
# Do something
# bar() is decorated
このメカニズムは、懸念を分離し、関数またはメソッドのコアロジックを「汚染する」外部の関連しないロジックを回避するのに便利です。 デコレーションでうまく処理される機能の良い例は memoization またはキャッシングです: 高価な関数の結果を 既に計算されているときにそれらを再計算する代わりに直接使用することができます。 これは明らかに関数ロジックの一部ではありません。
コンテキストマネージャ¶
コンテキストマネージャは、アクションに余分なコンテキスト情報を提供するPythonオブジェクトです。 この余分な情報は、 with
文を使って文脈を開始すると同時に、 with
ブロック内のすべてのコードを完了したときに呼び出し可能なものを実行するという形で呼び出すことができます。 コンテキストマネージャを使用する最もよく知られている例をここに示し、ファイルを開きます:
with open('file.txt') as f:
contents = f.read()
このパターンに精通している人は、このように open
を呼び出すと、ある時点で f
の close
メソッドが呼び出されることが保証されます。 これにより、開発者の認知負荷が軽減され、コードが読みやすくなります。
この機能を実装するには、クラスを使用する方法とジェネレータを使用する方法があります。 クラスのアプローチから始めて、上記の機能を自分で実装しましょう:
class CustomOpen(object):
def __init__(self, filename):
self.file = open(filename)
def __enter__(self):
return self.file
def __exit__(self, ctx_type, ctx_value, ctx_traceback):
self.file.close()
with CustomOpen('file') as f:
contents = f.read()
これは単に with
文で使われる2つの余分なメソッドを持つ普通のPythonオブジェクトです。 CustomOpenが最初にインスタンス化され、 __enter__
メソッドが呼び出され、 __enter__
が返すものは、文の as
部分の f
に代入されます。 with
ブロックの内容の実行が終了すると、 __exit__
メソッドが呼び出されます。
そして、Python独自のジェネレータを使ったアプローチは contextlib:
from contextlib import contextmanager
@contextmanager
def custom_open(filename):
f = open(filename)
try:
yield f
finally:
f.close()
with custom_open('file') as f:
contents = f.read()
これは上のクラスの例とまったく同じように動作しますが、もっと簡潔です。 custom_open
関数は、 yield
ステートメントに達するまで実行されます。次に with
文に制御を戻し、 as
部分に f
の yield
を割り当てます。 finally
節は、 with
の中に例外があったかどうかにかかわらず、 close()
が呼び出されるようにします。
2つのアプローチが同じように見えるので、PythonのZenに従っていつ使うべきかを決める必要があります。クラスのアプローチは、カプセル化するロジックが相当量ある場合には効果的です。ファンクションのアプローチは、単純なアクションを扱う場合には適しています。
動的タイピング¶
Pythonは動的に型付けされています。つまり、変数には固定型がありません。 実際、Pythonでは、変数は他の多くの言語、特に静的型の言語とは大きく異なります。 変数は、値が書き込まれるコンピュータのメモリのセグメントではなく、オブジェクトを指す「タグ」または「名前」です。 したがって、変数 ‘a’を値1に設定し、値 ‘文字列’に設定してから関数に設定することができます。
Pythonの動的型付けはしばしば弱点とみなされ、実際には複雑で難しいコードにつながる可能性があります。 ‘a’という名前のものはさまざまなものに設定することができ、開発者や管理者は完全に無関係のオブジェクトに設定されていないことを確認するためにこの名前をコード内で追跡する必要があります。
この問題を回避するガイドラインがいくつかあります。
- 異なる変数に同じ変数名を使用しないでください。
悪い
a = 1
a = 'a string'
def a():
pass # Do something
良い
count = 1
msg = 'a string'
def func():
pass # Do something
短い関数やメソッドを使用すると、無関係な2つのものに対して同じ名前を使用するリスクを軽減できます。
異なるタイプのものでも、関連するものであっても、異なる名前を使用する方が良いでしょう。
悪い
items = 'a b c d' # This is a string...
items = items.split(' ') # ...becoming a list
items = set(items) # ...and then a set
名前を再利用すると効率は上がりません。割り当ては新しいオブジェクトを作成する必要があります。 しかし、複雑さが増し、それぞれの割り当てが ‘if’ブランチやループを含む他のコード行で分かれている場合、与えられた変数の型が何であるかを確かめることは難しくなります。
関数型プログラミングのように、変数を再割り当てすることを決して推奨していないコーディングもあります。 Javaでは、これは final キーワードで行います。 Pythonは final キーワードを持っておらず、とにかくその哲学に反するでしょう。しかし、変数に複数回代入するのを避けることは良い規律かもしれませんし、可変で不変な型の概念を理解するのに役立ちます。
変更可能および変更不可能な型¶
Pythonには、組み込み型とユーザー定義型の2種類があります。
ミュータブルなタイプは、コンテンツのインプレース変更を可能にするタイプです。 典型的なミュータブルはリストと辞書です: 全てのリストには list.append()
や list.pop()
のようなメソッドの変更があります。 辞書についても同じことが言えます。
イミュータブルは、内容を変更するためのメソッドを提供しません。 例えば、変数xに整数6を設定すると、「インクリメント」メソッドはありません。 x + 1を計算する場合は、別の整数を作成して名前を付ける必要があります。
my_list = [1, 2, 3]
my_list[0] = 4
print my_list # [4, 2, 3] <- The same list as changed
x = 6
x = x + 1 # The new x is another object
この動作の違いの1つの結果として、ミュータブルなタイプは「安定」ではないため、辞書キーとして使用することはできません。
自然に変更可能なものに対しては適切にミュータブルな型を使用し、性質上固定されているものに対してはイミュータブルなタイプを使用すると、コードの意図を明確にするのに役立ちます。
例えば、リストの不変な等価物は (1, 2)
で作られたタプルです。このタプルは、インプレースで変更できないペアであり、辞書のキーとして使用できます。
初心者を驚かせることができるPythonの特徴の1つは、文字列が不変であることです。 つまり、パーツから文字列を作成するときには、リスト内に変更可能なパーツを累積して、フルストリングが必要なときにパーツ同士を接着 (‘join’) する方がはるかに効率的です。 しかし、注意すべき点の1つは、リスト内包は、 append()
を呼び出してループ内にリストを構築するよりも優れていて速いということです。
悪い
# create a concatenated string from 0 to 19 (e.g. "012..1819")
nums = ""
for n in range(20):
nums += str(n) # slow and inefficient
print nums
良い
# create a concatenated string from 0 to 19 (e.g. "012..1819")
nums = []
for n in range(20):
nums.append(str(n))
print "".join(nums) # much more efficient
ベスト
# create a concatenated string from 0 to 19 (e.g. "012..1819")
nums = [str(n) for n in range(20)]
print "".join(nums)
文字列について言及する最後の1つは、 join()
を使うことが必ずしも最良ではないということです。あらかじめ決められた数の文字列から新しい文字列を作成する場合は、加算演算子を使用するほうが高速ですが、上記のような場合や既存の文字列に追加する場合は join()
の方が好ましいでしょう。
foo = 'foo'
bar = 'bar'
foobar = foo + bar # This is good
foo += 'ooo' # This is bad, instead you should do:
foo = ''.join([foo, 'ooo'])
注釈
また、 % フォーマット演算子を使って、str.join()
と +
のほかにあらかじめ決められた数の文字列を連結することもできます。 しかし、PEP 3101 は、str.format()
メソッドのために %
演算子の使用を奨励しています。
foo = 'foo'
bar = 'bar'
foobar = '%s%s' % (foo, bar) # It is OK
foobar = '{0}{1}'.format(foo, bar) # It is better
foobar = '{foo}{bar}'.format(foo=foo, bar=bar) # It is best
ベンダー依存の依存関係¶
ランナー¶
コードスタイル¶
PythonプログラマーにPythonについて最も好きなものを尋ねると、彼らはしばしば高い可読性を挙げるでしょう。 確かに、コードは書かれたよりもずっと頻繁に読み込まれるという認識された事実に従うことで、高いレベルの可読性がPython言語の設計の中心にあります。
Pythonコードの可読性が高い理由の1つは、コードスタイルガイドラインとPythonのイディオムの比較的完全なセットです。
ベテランのPython開発者(Pythonista)が、コードの部分について “Pythonic” ではないと呼ぶとき、通常は、これらのコード行が共通のガイドラインに従っておらず、その意図を最良(最も読み取りやすい)と考えられる方法で表現できていないことを意味します。
いくつかの境界ケースでは、Pythonコードで意図を表現するための最良の方法については合意されていませんが、これらのケースはまれです。
一般的な概念¶
明示的なコード¶
Pythonではあらゆる種類の黒魔術が可能ですが、最も明快で簡単な方法が好まれます。
悪い
def make_complex(*args):
x, y = args
return dict(**locals())
良い
def make_complex(x, y):
return {'x': x, 'y': y}
上記の良いコードでは、xとyは呼び出し元から明示的に受け取られ、明示的な辞書が返されます。 この関数を使用している開発者は、最初と最後の行を読むことによって何をすべきかを正確に知っていますが、悪い例ではそうではありません。
行ごとに1つのステートメント¶
リスト内包表記のようないくつかの複合文は、その簡潔さと表現力のために許可され、評価されますが、同じコード行に2つの分離した文を持つことは悪い習慣です。
悪い
print 'one'; print 'two'
if x == 1: print 'one'
if <complex comparison> and <other complex comparison>:
# do something
良い
print 'one'
print 'two'
if x == 1:
print 'one'
cond1 = <complex comparison>
cond2 = <other complex comparison>
if cond1 and cond2:
# do something
関数の引数¶
引数は4つの異なる方法で関数に渡すことができます。
- 位置引数 は必須であり、デフォルト値はありません。それらは引数の最も単純な形式であり、関数の意味の一部であり、順序は自然であるいくつかの関数引数に対して使用できます。例えば、
send(message, recipient)
やpoint(x, y)
では、関数のユーザは2つの引数を必要とします。
この2つのケースでは、関数を呼び出すときに引数名を使用することができます。そうすることで、引数の順序を切り替えることができます。例えば、send(recipient='World', message='Hello')
と point(y=2, x=1)
を呼び出す引数の順序を send('Hello', 'World')
と Point(1,2)
に切り替えることが可能ですが、これは可読性を低下させ、不必要で冗長です。
- キーワード引数 は必須ではなく、デフォルト値を持ちます。これらは、関数に送信されるオプションのパラメータによく使用されます。関数に2つまたは3つ以上の位置パラメータがある場合、そのシグネチャは覚えにくいため、キーワード引数をデフォルト値で使用すると便利です。例えば、より完全な
send
関数はsend(message, to, cc=None, bcc=None)
として定義できます。ここで、cc
とbcc
はオプションで、別の値が渡されないときはNone
と評価されます。
キーワード引数を持つ関数をPythonで複数の方法で呼び出すことができます。たとえば、 send('Hello', 'World', 'Cthulhu', 'God')
のように、引数に明示的に名前を付けずにカーボンコピーを送る。 send('Hello again', 'World', bcc='God', cc='Cthulhu')
のように、別の順序で引数を指定することもできます。 send('Hello', 'World', cc='Cthulhu', bcc='God')
関数の定義に最も近い構文に従わないという強い理由がなくても。
副作用として、 YAGNI 原則の後で、オプションの引数(およびその関数内のロジック)を削除することは難しい場合があります。必要に応じて新しいオプションの引数とそのロジックを追加するよりも、まるで使用されていて一見無意味です。
- 任意の引数リスト は、引数を関数に渡す3番目の方法です。関数の意図が、拡張可能な数の位置引数を持つシグネチャによってうまく表現されている場合は、
* args
構造体で定義できます。関数本体では、args
は残りのすべての位置引数のタプルになります。たとえば、send('Hello', 'God', 'Mom', 'Cthulhu')
とsend(message, *args)
のように、関数本体args
は('God', 'Mom', 'Cthulhu')
に等しくなります。
しかしながら、この構築物にはいくつかの欠点があり、慎重に使用すべきです。ある関数が同じ性質の引数のリストを受け取った場合、それを1つの引数の関数として定義することがより明確であり、その引数はリストまたは任意のシーケンスです。ここで send
に複数の受信者がある場合、send('Hello', ['God', 'Mom', 'Cthulhu'])
で明示的に send(message, recipients)
。この方法では、関数のユーザーは受信者リストをあらかじめリストとして操作し、イテレーターを含む他のシーケンスとして解凍できないシーケンスを渡す可能性を開きます。
- 任意のキーワード引数辞書 は、関数に引数を渡す最後の方法です。 関数が未定義の一連の名前付き引数を必要とする場合は、
** kwargs
構造体を使用することができます。 関数本体では、kwargs
は、関数シグネチャ内の他のキーワード引数によってキャッチされていない、渡されたすべての名前付き引数の辞書になります。
同様の理由から、任意の引数リスト の場合と同じ注意が必要です。これらの強力な手法は、実証された必要性がある場合に使用されるものであり、よりシンプルで明確な構成が関数の意図を十分に表現することが可能です。
どの引数が定位置引数であり、かつオプションのキーワード引数であるかを決定し、任意の引数渡しの高度な技術を使用するかどうかを決定するのは、関数を記述するプログラマの責任です。上記のアドバイスが賢明に守られれば、Pythonの関数を書くことが楽しくなるでしょう:
- 読みやすい(名前と引数は説明が不要)
- 簡単に変更することができます(新しいキーワード引数を追加することでコードの他の部分が破られることはありません)
魔法の杖を避ける¶
ハッカー向けの強力なツールであるPythonには、非常に豊富なフックやツールが付属しており、あらゆる種類のトリッキーなトリックを行うことができます。 例えば、以下について行うことができます。
- オブジェクトの作成およびインスタンス化の方法を変更する
- Pythonインタープリタがどのようにモジュールをインポートするかを変更する
- CのルーチンをPythonに埋め込むことも可能です(必要に応じてお勧めします)
しかし、これらのオプションには多くの欠点があります。目標を達成するためには、最も簡単な方法を使用する方が常に優れています。 主な欠点は、これらのコンストラクトを使用すると可読性が大幅に低下することです。 pylintやpyflakesなどの多くのコード解析ツールは、この「魔法の」コードを解析できません。
私たちは、Pythonの開発者は、これらの無限の可能性について知っておくべきだと考えています。なぜなら、途方もなく問題が起こらないという自信があるからです。 しかし、どのように、特に使用 しない かを知ることは非常に重要です。
カンフーのマスターのように、Pythonistaは単一の指で殺す方法を知っています。 実際にそれをすることは決してありません。
私たちはすべて責任あるユーザーです¶
上で見たように、Pythonは多くのトリックを許し、そのうちのいくつかは潜在的に危険です。良い例は、どんなクライアントコードでも、オブジェクトのプロパティとメソッドをオーバーライドすることができるということです。Pythonでは “private”キーワードはありません。このような哲学は、誤用を防ぐための多くの仕組みを提供するJavaのような高度に防御的な言語とは異なり、「私たちはすべての責任あるユーザーです」と表現されています。
これは、例えばプロパティがプライベートであるとはみなされず、Pythonでは適切なカプセル化ができないことを意味しません。 Pythonコミュニティは、開発者がコードと他のコードの間に構築したコンクリートの壁に頼るのではなく、これらの要素に直接アクセスすべきではないことを示す一連の規則に頼っています。
プライベートプロパティと実装の詳細の主な慣例は、すべての “内部”にアンダースコアを付けることです。 クライアントコードがこのルールを破ってこれらのマークされた要素にアクセスする場合、コードが変更された場合に遭遇する不正行為や問題は、クライアントコードの責任です。
このコンベンションを惜しみなく使用することをお勧めします。クライアントコードで使用されないメソッドやプロパティには、アンダースコアを前に付ける必要があります。 これにより、任務の分離と既存のコードの変更が容易になります。 プライベートプロパティを公開することは常に可能ですが、パブリックプロパティをプライベートにすることは、非常に難しい操作になる可能性があります。
戻り値¶
関数が複雑になると、関数本体に複数のreturn文を使用することは珍しくありません。しかし、明確な意図と持続可能な可読性レベルを維持するためには、身体の多くの出力点から意味のある値を返すことを避けることが望ましいです。
関数内で値を返す主なケースが2つあります。関数の結果が正常に処理されたときの結果と、誤った入力パラメータを示すエラーケース、または関数が計算を完了できないその他の理由またはタスクです。
2番目のケースの例外を発生させたくない場合は、関数が正しく実行できなかったことを示すNoneやFalseなどの値を返す必要があります。 この場合、間違ったコンテキストが検出されたときに早く戻ってください。 関数の構造をフラット化するのに役立ちます。return-of-errorステートメントの後のすべてのコードは、関数の主な結果をさらに計算するために条件が満たされたとみなすことができます。 多くの場合、そのようなreturn文が必要です。
しかし、ある関数が通常のコースに対して複数のメイン出口点を持つ場合、返された結果をデバッグするのが難しくなるため、単一の出口点を保つことが望ましい場合があります。 これはまた、いくつかのコードパスを抽出するのにも役立ちます。また、複数の出口ポイントがそのようなリファクタリングが必要であることを示す可能性があります。
def complex_function(a, b, c):
if not a:
return None # Raising an exception might be better
if not b:
return None # Raising an exception might be better
# Some complex code trying to compute x from a, b and c
# Resist temptation to return x if succeeded
if not x:
# Some Plan-B computation of x
return x # One single exit point for the returned value x will help
# when maintaining the code.
イディオム¶
簡単に言えば、プログラミングのイディオムは、コードを書く 方法 です。プログラミングイディオムの概念については、 c2 と Stack Overflow です。
慣用的なPythonコードは Pythonic と呼ばれることが多い。
通常は、それを実行するための1つの方法、好ましくは1つの方法しかありません。 慣用のPythonコードを書く 方法は、Pythonの初心者には明らかではありません。 ですから、良い熟語を意識的に獲得しなければなりません。
いくつかの一般的なPythonのイディオムが続きます:
解凍¶
リストやタプルの長さを知っている場合、その要素に名前をつけることができます。 たとえば、 enumerate()
はlistの各項目に対して2つの要素のタプルを提供します:
for index, item in enumerate(some_list):
# do something with index and item
変数をスワップするときにもこれを使うことができます:
a, b = b, a
ネストされたアンパックも機能します:
a, (b, c) = 1, (2, 3)
Python 3では、拡張アンパックの新しいメソッドが次のように導入されました PEP 3132:
a, *rest = [1, 2, 3]
# a = 1, rest = [2, 3]
a, *middle, c = [1, 2, 3, 4]
# a = 1, middle = [2, 3], c = 4
無視された変数を作成する¶
何かを割り当てる必要がある場合(例えば、unpacking-ref)、その変数は必要ないでしょう。__
を使ってください:
filename = 'foobar.txt'
basename, __, ext = filename.rpartition('.')
注釈
多くのPythonスタイルガイドでは、ここで推奨される二重アンダースコア “__
” ではなく、使い捨て変数に単一のアンダースコア “_
“を使用することを推奨しています。 問題は、 “_
” は gettext()
関数のエイリアスとしてよく使われ、最後の操作の値を保持するために対話型プロンプトでも使われます。 代わりに二重のアンダースコアを使用することは、明らかであり、ほぼ同じくらい便利で、これらの他のユースケースのいずれかを誤って妨害するリスクを排除します。
リストの長さNのリストを作成する¶
リストは変更可能であるため、 *
演算子(上記のように)は same リストに対するN個の参照のリストを作成します。 代わりに、リストの理解を使用します。
four_lists = [[] for __ in xrange(4)]
Note: Python 3では xrange() の代わりに range() を使用してください
リストから文字列を作成する¶
文字列を作成する一般的な方法は、空の文字列に str.join()
を使用することです。
letters = ['s', 'p', 'a', 'm']
word = ''.join(letters)
変数 word の値を ‘spam’ に設定します。 このイディオムは、リストやタプルに適用できます。
コレクション内のアイテムを検索する¶
時々、私たちは物事のコレクションを検索する必要があります。リストとセットの2つのオプションを見てみましょう。
例えば、次のコードを実行します:
s = set(['s', 'p', 'a', 'm'])
l = ['s', 'p', 'a', 'm']
def lookup_set(s):
return 's' in s
def lookup_list(l):
return 's' in l
- lookup_set はPythonのセットがハッシュテーブルであるという事実を利用しているので、両方の関数が同じに見えますが、2つのルックアップのパフォーマンスは大きく異なります。項目がリストにあるかどうかを判断するには、Pythonは一致する項目が見つかるまで各項目を調べなければなりません。これは時間がかかります。長いリストの場合は特にそうです。一方、あるセットでは、アイテムのハッシュは、セット内のどこで一致するアイテムを探すかをPythonに指示します。その結果、セットが大きい場合であっても、迅速に検索を行うことができます。辞書での検索も同じように機能します。詳細は、この StackOverflow ページを参照してください。これらのデータ構造のそれぞれに共通するさまざまな操作の詳細については、 このページ を参照してください。これらのパフォーマンスの違いのため、リストの代わりにセットまたは辞書を使用することは、良い考えであると言えます。:
これらのパフォーマンスの違いにより、リストの代わりにセットまたは辞書を使用することがよくあります。
- コレクションには多数のアイテムが含まれます
- コレクション内のアイテムを繰り返し検索します
- 重複アイテムはありません
小さなコレクション、または頻繁に検索しないコレクションの場合、ハッシュテーブルを設定するために必要な時間とメモリが、検索速度が向上した時間よりも長くなることがよくあります。
Pythonの禅¶
PEP 20 とも呼ばれ、Pythonの設計の基本原則です。
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
よいPythonスタイルのいくつかの例については、 Pythonユーザグループのこれらのスライド を参照してください。
PEP 8¶
PEP 8 はPythonの事実上のコードスタイルガイドです。 pep8.org には、高品質で読みやすいPEP 8のバージョンもあります。
これは強くお勧めします。 Pythonコミュニティ全体は、このドキュメント内に記載されているガイドラインを守るために最善を尽くしています。 プロジェクトの中には時々動揺するものもあれば、 その勧告を修正するものもあります 。
つまり、PythonコードをPEP 8に準拠させることは、一般的には良いアイデアであり、他の開発者と一緒にプロジェクトを作業する場合にコードをより一貫性のあるものにするのに役立ちます。 あなたのコードの適合性をチェックできるコマンドラインプログラム pep8 があります。 ターミナルで次のコマンドを実行してインストールします。
$ pip install pep8
次に、ファイルまたは一連のファイルに対して実行して、違反の報告を取得します。
$ pep8 optparse.py
optparse.py:69:11: E401 multiple imports on one line
optparse.py:77:1: E302 expected 2 blank lines, found 1
optparse.py:88:5: E301 expected 1 blank line, found 0
optparse.py:222:34: W602 deprecated form of raising exception
optparse.py:347:31: E211 whitespace before '('
optparse.py:357:17: E201 whitespace after '{'
optparse.py:472:29: E221 multiple spaces before operator
optparse.py:544:21: W601 .has_key() is deprecated, use 'in'
autopep8 プログラムを使って、PEP 8形式のコードを自動的に再フォーマットすることができます。 次のようにプログラムをインストールします。
$ pip install autopep8
これを使用して、次のようにファイルをインプレースでフォーマットします。
$ autopep8 --in-place optparse.py
--in-place
フラグを除外すると、プログラムは変更されたコードをレビューのためにコンソールに直接出力します。 --aggressive
フラグはより実質的な変更を行い、効果を高めるために複数回適用することができます。
コンベンション¶
あなたのコードを読みやすくするために従わなければならない規則がいくつかあります。
変数が定数に等しいかどうかをチェックする¶
明示的に値をTrue、None、または0と明示的に比較する必要はありません。if文に値を追加するだけです。 誤っていると思われるもののリストについては、 真理値テスト を参照してください。
悪い:
if attr == True:
print 'True!'
if attr == None:
print 'attr is None!'
良い:
# Just check the value
if attr:
print 'attr is truthy!'
# or check for the opposite
if not attr:
print 'attr is falsey!'
# or, since None is considered false, explicitly check for it
if attr is None:
print 'attr is None!'
辞書要素へのアクセス¶
dict.has_key()
メソッドを使わないでください。 その代わりに、 x in d
構文を使うか、デフォルト引数を dict.get()
に渡します。
悪い:
d = {'hello': 'world'}
if d.has_key('hello'):
print d['hello'] # prints 'world'
else:
print 'default_value'
良い:
d = {'hello': 'world'}
print d.get('hello', 'default_value') # prints 'world'
print d.get('thingy', 'default_value') # prints 'default_value'
# Or:
if 'hello' in d:
print d['hello']
リストを操作するための短い方法¶
List comprehensions は、リストを扱うための強力かつ簡潔な方法を提供します。 また、map()
と filter()
関数は、より簡潔で異なった構文を使ってリストに対して操作を実行できます。
悪い:
# Filter elements greater than 4
a = [3, 4, 5]
b = []
for i in a:
if i > 4:
b.append(i)
良い:
a = [3, 4, 5]
b = [i for i in a if i > 4]
# Or:
b = filter(lambda x: x > 4, a)
悪い:
# Add three to all list members.
a = [3, 4, 5]
for i in range(len(a)):
a[i] += 3
良い:
a = [3, 4, 5]
a = [i + 3 for i in a]
# Or:
a = map(lambda i: i + 3, a)
使用 enumerate()
リスト内のあなたの場所の数を保持します。
a = [3, 4, 5]
for i, item in enumerate(a):
print i, item
# prints
# 0 3
# 1 4
# 2 5
enumerate()
関数はカウンタを手動で扱うよりも読み易いです。 さらに、イテレータの方が最適化されています。
ファイルからの読み取り¶
ファイルから読み込むには with open
構文を使用します。 これにより、自動的にファイルが閉じられます。
悪い:
f = open('file.txt')
a = f.read()
print a
f.close()
良い:
with open('file.txt') as f:
for line in f:
print line
with
ステートメントは、 with
ブロック内で例外が発生したとしても、ファイルを常に確実に閉じることができるので、より優れています。
行の継続¶
論理行のコードが許容限度より長い場合は、複数の物理行に分割する必要があります。 行の最後の文字がバックスラッシュの場合、Pythonインタプリタは連続する行を結合します。 これはいくつかの場合に役立ちますが、通常、その脆弱性のために回避する必要があります。バックスラッシュの後ろの行末に空白を追加すると、コードが壊れて予期しない結果になることがあります。
より良い解決策は、要素の周りに括弧を使用することです。 行末に閉じられていない括弧が残っていると、Pythonインタプリタは括弧が閉じられるまで次の行に結合します。 中括弧と中括弧も同じ動作をします。
悪い:
my_very_big_string = """For a long time I used to go to bed early. Sometimes, \
when I had put out my candle, my eyes would close so quickly that I had not even \
time to say “I’m going to sleep.”"""
from some.deep.module.inside.a.module import a_nice_function, another_nice_function, \
yet_another_nice_function
良い:
my_very_big_string = (
"For a long time I used to go to bed early. Sometimes, "
"when I had put out my candle, my eyes would close so quickly "
"that I had not even time to say “I’m going to sleep.”"
)
from some.deep.module.inside.a.module import (
a_nice_function, another_nice_function, yet_another_nice_function)
しかし、しばしば長い論理行を分割しなければならないことは、同時に多くのことをしようとしている兆候であり、読みやすさの妨げになりかねません。
優れたコードを読む¶
Pythonの設計の背後にある主な原則の1つは、読み取り可能なコードを作成することです。 この設計の背景にある動機は簡単です: Pythonプログラマが行う最も重要なことはコードを読むことです。
優れたPythonプログラマーになるための秘訣の1つは、優れたコードを読み、理解することです。
優れたコードは、通常 code_style に概説されているガイドラインに従っており、読者に明確かつ簡潔な意図を表現するために最善を尽くしています。
以下に、読むための推奨されるPythonプロジェクトのリストを示します。それぞれのプロジェクトは、Pythonコーディングの模範です。
- Howdoi HowdoiはPythonで書かれたコード検索ツールです。
- Flask Flaskは、WerkzeugとJinja2に基づくPython用のマイクロフレームワークです。これは非常に迅速に開始することを目的としており、最善の意図を念頭に開発されています。
- Diamond Diamondは、メトリックを収集してGraphiteや他のバックエンドに公開するpythonデーモンです。 これは、CPU、メモリ、ネットワーク、I/O、負荷とディスクのメトリックを収集することができます。 さらに、ほとんどのソースからメトリックを収集するカスタムコレクタを実装するためのAPIを備えています。
- Werkzeug Werkzeug は、WSGIアプリケーション用のさまざまなユーティリティの単純なコレクションとして始まり、最も高度なWSGIユーティリティモジュールの1つになっています。 強力なデバッガ、フル機能のリクエストとレスポンスのオブジェクト、エンティティタグ、キャッシュコントロールヘッダー、HTTPの日付、クッキーの処理、ファイルのアップロード、強力なURLルーティングシステム、およびコミュニティによって提供されるアドオンモジュールの束を処理するHTTPユーティリティが含まれています。
- Requests RequestsはPythonで書かれたApache2ライセンスHTTPライブラリです。
- Tablib Tablibは、Pythonで書かれた、フォーマットに依存しない表形式のデータセットライブラリです。
課題
リストされた各プロジェクトの模範的なコードのコード例を含みます。 それが優れたコードである理由を説明してください。 複雑な例を使用します。
課題
データ構造、アルゴリズムを迅速に特定し、コードが何をしているのかを判断するためのテクニックを説明します。
ドキュメンテーション¶
可読性は、プロジェクトとコードのドキュメント両方ともPython開発者の主な焦点となっています。いくつかの簡単なベストプラクティスに従えば、あなたと他の人の両方に多くの時間を節約できます。
プロジェクトのドキュメント¶
ルートディレクトリにある README
ファイルは、プロジェクトのユーザと管理者の両方に一般的な情報を与えるべきです。生のテキストでなければなりません。例えば reStructuredText やMarkdownのような読みやすいマークアップで記述します。プロジェクトやライブラリの目的(ユーザーがプロジェクトについて知っていることを前提としない)、ソフトウェアの主なソースのURL、および基本的なクレジット情報を説明する行がいくつか含まれていなければなりません。このファイルは、コードの読者のための主要なエントリポイントです。
Pythonでは INSTALL
ファイルはあまり必要ありません。 インストール指示は pip install module
や python setup.py install
のように1つのコマンドに短縮され、README
ファイルに追加されます。
LICENSE
ファイルは常に存在し、ライセンスを指定する必要があります
その下でソフトウェアは一般に公開されます。
TODO
ファイルまたは TODO
セクション README
は、コードの開発予定を列挙します。
CHANGELOG
ファイルまたはセクション README
は、最新バージョンのコードベースの変更の概要をコンパイルする必要があります。
プロジェクト出版¶
プロジェクトによっては、ドキュメントに次のコンポーネントの一部またはすべてが含まれている場合があります。
- introduction には、1つまたは2つの非常に単純化されたユースケースを使用して、製品でできることの概要を非常に簡単に示してください。これはあなたのプロジェクトのための30秒のピッチです。
- チュートリアル では、いくつかの主要なユースケースをより詳細に示す必要があります。読者は、実際のプロトタイプをセットアップするための段階的な手順に従います。
- APIリファレンス は通常、コードから生成されます(参照 docstrings)。これは、公開されているすべてのインターフェース、パラメーター、および戻り値をリストします。
- 開発者ドキュメント は、潜在的な貢献者を対象としています。 これには、プロジェクトのコード規約と一般的なデザイン戦略が含まれます。
Sphinx¶
Sphinx は、最も人気のあるPythonドキュメントツールです。 これを使用します。 reStructuredText マークアップ言語を、HTML、LaTeX(印刷可能なPDF版用)、マニュアルページ、プレーンテキストなどの出力フォーマットの範囲に変換します。
あなたの Sphinx docsのための 無料で、素晴らしい ホスティングもあります: Read The Docs。 これを使用します。 ドキュメントの再構築が自動的に行われるように、ソースリポジトリへのコミットフックを設定することができます。
実行すると、Sphinx はコードをインポートし、Pythonのイントロスペクション機能を使用して、すべての関数、メソッド、クラスのシグネチャを抽出します。 また付属のドキュメントストリングを抽出し、それをすべて構造化された、簡単に読めるドキュメントにコンパイルしてプロジェクトに合わせます。
注釈
SphinxはAPIの生成で有名ですが、一般的なプロジェクトのドキュメントでもうまく機能します。 このガイドはSphinx_ で構築され、 Read The Docs でホスティングされています。
reStructuredText¶
ほとんどのPythonのドキュメントはreStructuredText_で書かれています。 Markdownのように、すべてのオプションの拡張が組み込まれています。
reStructuredText Primer と reStructuredText Quick Reference は、その構文に慣れるのに役立ちます。
コードドキュメントのアドバイス¶
コメントはコードを明確にし、コードを分かりやすくする目的で追加されています。 Pythonでは、コメントはハッシュ (数字記号) (#
) で始まります。
Pythonでは、docstrings はモジュール、クラス、関数を記述します:
def square_and_rooter(x):
"""Return the square root of self times self."""
...
一般的に、 PEP 8#comments (“Python Style Guide”) のコメントセクションに従ってください。 docstringの詳細については、PEP 0257#specification (Docstring規約ガイド)を参照してください。
コードのセクションのコメント¶
トリプルクォート文字列を使用してコードにコメントを付けないでください。 grepのような行指向のコマンドラインツールは、コメント付きコードが非アクティブであることを認識しないため、これは良い方法ではありません。コメント行ごとに適切なインデントレベルでハッシュを追加する方がよいでしょう。あなたのエディタはおそらくこれを簡単に実行する能力があり、コメント/コメント解除トグルを学ぶ価値があります。
ドキュメンテーションとマジック¶
一部のツールでは、ドキュメントテストロジックなどのドキュメントよりも多くの動作を埋め込むためにドキュメントストリングを使用します。 それらは素晴らしいことができますが、あなたは vanilla に間違って行くことはありません “ここでこれが何かをしています”。
Sphinx のようなツールは、ドキュメントストリングをreStructuredTextとして解析し、HTMLとして正しくレンダリングします。 これにより、サンプルコードのスニペットをプロジェクトのドキュメントに埋め込むことが非常に簡単になります。
さらに、Doctest_は、Pythonのコマンドライン( “>>>”という接頭辞)の入力と同じように見える埋め込みdocstringをすべて読み込み、コマンドの出力が次の行のテキストと一致するかどうかを確認します。 これにより、開発者は実際のサンプルと関数の使用方法をソースコードとともに埋め込むことができ、副作用として、コードがテストされ、動作することが保証されます。
def my_function(a, b):
"""
>>> my_function(2, 3)
6
>>> my_function('a', 3)
'aaa'
"""
return a * b
Docstringsとブロックコメント¶
これらは交換できません。関数またはクラスの場合、先頭のコメントブロックはプログラマーのメモです。 docstringは、関数またはクラスの operation を記述します:
# This function slows down program execution for some reason.
def square_and_rooter(x):
"""Returns the square root of self times self."""
...
ブロックコメントとは異なり、docstrings はPython言語自体に組み込まれています。 つまり、Pythonの強力なイントロスペクション機能をすべて使用して、最適化されたコメントと比較して、実行時に docstrings にアクセスすることができます。 Docstringは、ほとんどすべてのPythonオブジェクトのための __doc__ dunder属性と組み込みの help() 関数の両方からアクセスできます。
ブロックのコメントは通常、コードの何が何をしているのか、アルゴリズムの詳細を説明するために使われますが、docstringは他のユーザにあなたのコードを説明するためのものです(6ヶ月以内に) how 関数、クラス、モジュールの汎用目的に使用できます。
ドキュメントストリングを書く¶
関数、メソッド、またはクラスの複雑さに応じて、1行のdocstringが完全に適切かもしれません。 これらは一般的に次のような本当の明白な場合に使用されます:
def add(a, b):
"""Add two numbers and return the result."""
return a + b
docstringは、理解しやすい方法で関数を記述する必要があります。 簡単な関数やクラスのような簡単な場合は、関数のシグネチャ (つまり、add(a, b) -> result) をdocstringに埋め込むだけで済みます。 これは、Pythonの inspect モジュールでは、必要に応じてこの情報を見つけるのがとても簡単で、ソースコードを読むことで簡単に入手できるからです。
しかし、より大規模なプロジェクトやより複雑なプロジェクトでは、関数、それが行うこと、発生する可能性のある例外、返されるもの、またはパラメータに関する関連する詳細に関する情報を多く与えることは、しばしば良い考えです。
コードのより詳細なドキュメンテーションについては、Numpyプロジェクトがよく使われます。 Numpy style と呼ばれることもあります。 これは前の例をいくつか追加していますが、開発者はメソッド、関数、またはクラスに関するさらに多くの情報を含めることができます。:
def random_number_generator(arg1, arg2):
"""
Summary line.
Extended description of function.
Parameters
----------
arg1 : int
Description of arg1
arg2 : str
Description of arg2
Returns
-------
int
Description of return value
"""
return 42
sphinx.ext.napoleon プラグインは、Sphinx がこのスタイルのドキュメントストリングを解析できるようにし、NumPyスタイルのドキュメントストリングをプロジェクトに簡単に組み込むことができます。
その日の終わりには、ドキュメントストリングを書くためにどのようなスタイルが使われているかは重要ではありません。その目的は、コードを読んだり変更したりする必要がある人のためのドキュメンテーションとして役立つことです。 それを正しく理解できるものであれば、関連するポイントを得ることができます。
ドキュメントストリングをさらに読むには、相談してください PEP 257
その他のツール¶
あなたは出回っているこれらを見るかもしれません。 Sphinx を使います。
- Pycco
- Pyccoは “識字プログラミングスタイルのドキュメント生成プログラム” であり、node.js Docco の一部です。 それはコードをサイド・バイ・サイドのHTMLコードとドキュメントにします。
- Ronn
- RonnはUnixのマニュアルを作成しています。 これは、人間が読めるテキストファイルをターミナル表示のためにroffに、そしてウェブのHTMLに変換します。
- MkDocs
- MkDocsは、Markdownでプロジェクトのドキュメンテーションを構築するための、高速でシンプルな静的サイト生成ツールです。
コードのテスト¶
コードをテストすることは非常に重要です。
テストコードを書くことに慣れ、このコードを並行して実行することは、現在、良い習慣と考えられています。この方法は賢明に使用され、コードの意図をより正確に定義し、より分離されたアーキテクチャを持つのに役立ちます。
いくつかの一般的なテストのルール:
- テストユニットは1つの機能のほんの少しに集中し、それが正しいことを証明する必要があります。
- 各試験ユニットは完全に独立していなければなりません。各テストは、呼び出される順番に関係なく、単独で実行できなければならず、テストスイート内でも実行できなければなりません。このルールの意味は、各テストに新しいデータセットがロードされていなければならず、後で何らかのクリーンアップを行わなければならない可能性があるということです。これは通常
setUp()
とtearDown()
メソッドで処理されます。
- テストを高速化するのは難しいです。 1回のテストに数ミリ秒以上の時間がかかる場合は、開発が遅くなるか、またはテストが望ましいほど頻繁に実行されません。場合によっては、複雑なデータ構造が必要であり、テストが実行されるたびにこのデータ構造をロードする必要があるため、テストを高速化することはできません。これらのより重いテストは、スケジュールされたタスクによって実行される別のテストスイートに保管し、必要に応じて他のすべてのテストを頻繁に実行します。
- あなたのツールを学び、単一のテストまたはテストケースを実行する方法を学びます。 次に、モジュール内の関数を開発するときは、この関数のテストを頻繁に、理想的にはコードを保存すると自動的に実行します。
- コーディングセッションの前に常に完全なテストスイートを実行してから、それをやり直してください。 これにより、残りのコードで何も壊れていないという確信が得られます。
- コードを共有リポジトリにプッシュする前に、すべてのテストを実行するフックを実装することをお勧めします。
- 開発セッションの途中で作業を中断しなければならない場合は、次に開発したいものについて壊れた単体テストを書くことをお勧めします。開発作業に戻ったときに、中断した続きへポインタを持っていくことができ、すぐに軌道に乗れるでしょう。
- コードをデバッグする最初のステップは、バグを特定する新しいテストを書くことです。必ずしもそうであるとは限りませんが、これらのバグを捕まえるテストは、プロジェクトの中で最も価値のあるコードです。
- テスト関数には長い記述的な名前を使用します。ここのスタイルガイドは、短い名前がしばしば好まれる実行コードとは少し異なります。なぜなら、テスト関数は決して明示的に呼び出されないからです。実行中のコードで
square()
やsqr()
でもOKですが、テストコードではtest_square_of_number_2()
,test_square_negative_number()
などの名前を使用します。これらの関数名は、テストが失敗したときに表示され、可能な限り説明的でなければなりません。
- 何かがうまくいかなかったり、変更が必要な場合、コードに適切なテストセットがある場合、あなたや他のメンテナはテストスイートに大きく依存して、問題を修正したり、特定の動作を修正します。 したがって、テストコードは、実行中のコードと同じくらい、あるいはそれ以上に読み込まれます。 その目的がはっきりしない単体テストは、この場合はあまり役に立ちません。
- テストコードのもう1つの使用方法は、新しい開発者を紹介することです。誰かがコードベースで作業しなければならない場合、関連するテストコードを実行して読むことが、しばしば彼らが始めるためにできる最善のことです。彼らは、最も困難が発生するホットスポット、およびコーナーケースを発見するでしょう。いくつかの機能を追加する必要がある場合は、最初にテストを追加して、新しい機能がインターフェイスにプラグインされていない現用パスでないことを確認します。
基本¶
ユニットテスト¶
unittest
は、Pythonの標準ライブラリに含まれるバッテリー同梱のテストモジュールです。 そのAPIは、JUnit/nUnit/CppUnitシリーズのいずれかを使用している人にとっては馴染み深いものです。
テストケースを作成するには、unittest.TestCase
をサブクラス化します。
import unittest
def fun(x):
return x + 1
class MyTest(unittest.TestCase):
def test(self):
self.assertEqual(fun(3), 4)
Python 2.7の時点で、unittestには独自のテスト検出メカニズムも含まれています。
Doctest¶
doctest
モジュールは、ドキュメンテーション文字列中のインタラクティブなPythonセッションのように見えるテキストを検索し、それらのセッションを実行して、表示されているとおりに動作することを確認します。
Doctestは、適切な単体テストとは異なるユースケースを持っています。通常、それは詳細は少なく、特殊なケースやあいまいな回帰バグは検出されません。 これらは、モジュールとそのコンポーネントの主な使用例を表現した文書として役立ちます。 ただし、doctestは、完全なテストスイートが実行されるたびに自動的に実行されます。
関数内の簡単なdoctest:
def square(x):
"""Return the square of x.
>>> square(2)
4
>>> square(-2)
4
"""
return x * x
if __name__ == '__main__':
import doctest
doctest.testmod()
python module.py
のようにコマンドラインからこのモジュールを実行すると、doctestは実行され、docstringに記述されているように動作していないものがあれば文句を言います。
ツール¶
py.test¶
py.testは、Pythonの標準的なunittestモジュールに代わるものではありません。
$ pip install pytest
完全に機能し、拡張可能なテストツールであるにもかかわらず、簡単な構文です。 テストスイートを作成するのは、以下の2つの機能を持つモジュールを作成するのと同じくらい簡単です。
# content of test_sample.py
def func(x):
return x + 1
def test_answer():
assert func(3) == 5
py.test コマンドを実行します
$ py.test
=========================== test session starts ============================
platform darwin -- Python 2.7.1 -- pytest-2.2.1
collecting ... collected 1 items
test_sample.py F
================================= FAILURES =================================
_______________________________ test_answer ________________________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
test_sample.py:5: AssertionError
========================= 1 failed in 0.02 seconds =========================
unittestモジュールと同等の機能に必要な作業よりはるかに少ない作業です!
Nose¶
noseはunittestを拡張してテストを容易にします。
$ pip install nose
noseは、テストスイートを手動で作成する手間を省くための自動テスト検出機能を提供します。 また、xUnitと互換性のあるテスト出力、カバレッジレポート、テストの選択など、多数のプラグインを提供します。
tox¶
toxは、テスト環境の管理を自動化し、複数のインタープリタ構成に対してテストするためのツールです
$ pip install tox
toxを使用すると、単純なini形式の構成ファイルを使用して、複雑な複数パラメータのテスト行列を構成できます。
Unittest2¶
unittest2は、Python 2.7のunittestモジュールのバックポートであり、改良されたAPIと以前のバージョンのPythonよりも優れたアサーションを備えています。
Python 2.6以降を使用している場合は、pipでインストールできます
$ pip install unittest2
将来的にモジュールの新しいバージョンへの移植コードをより簡単にするために、unittestという名前でモジュールをインポートすることができます
import unittest2 as unittest
class MyTest(unittest.TestCase):
...
こうすることで、新しいPythonバージョンに切り替えてunittest2モジュールが不要になった場合でも、他のコードを変更することなくテストモジュールのインポートを変更することができます。
mock¶
unittest.mock
はPythonでテストするためのライブラリです。 Python 3.3以降、これは 標準ライブラリ で利用可能です。
古いバージョンのPythonの場合:
$ pip install mock
テスト中のシステムの一部をモックオブジェクトに置き換え、それらがどのように使用されたかをアサーションすることができます。
For example, you can monkey-patch a method:
from mock import MagicMock
thing = ProductionClass()
thing.method = MagicMock(return_value=3)
thing.method(3, 4, 5, key='value')
thing.method.assert_called_with(3, 4, 5, key='value')
テスト中のモジュールのクラスやオブジェクトをモックするには、 patch
デコレータを使います。 以下の例では、外部検索システムが、常に同じ結果を返すモック(ただし、テストの期間のみ)に置き換えられています。
def mock_search(self):
class MockSearchQuerySet(SearchQuerySet):
def __iter__(self):
return iter(["foo", "bar", "baz"])
return MockSearchQuerySet()
# SearchForm here refers to the imported class reference in myapp,
# not where the SearchForm class itself is imported from
@mock.patch('myapp.SearchForm.search', mock_search)
def test_new_watchlist_activities(self):
# get_search_results runs a search and iterates over the result
self.assertEqual(len(myapp.get_search_results(q="fish")), 3)
Mockには他の多くの方法があります。
ロギング¶
logging
モジュールは、バージョン2.3以降のPythonの標準ライブラリの一部です。 PEP 282 に簡潔に記述されています。 基本的なロギングチュートリアル を除いて、ドキュメントは読みにくいことはよく知られています。
ロギングには2つの目的があります:
- 診断ログ は、アプリケーションの操作に関連するイベントを記録します。たとえば、ユーザーがエラーを報告するためにコールすると、ログでコンテキストを検索できます。
- 監査ロギング は、ビジネス分析のイベントを記録します。 ユーザーのトランザクションを抽出し、レポートの他のユーザーの詳細と組み合わせたり、ビジネス目標を最適化することができます。
...またはプリント?¶
コマンドラインアプリケーションのヘルプ文を表示するのがゴールのときだけ、 print
がロギングより良い選択肢です。 ロギングが print
より優れている理由:
- ログ記録イベントごとに作成される ログレコード は、ファイル名、フルパス、関数、ロギングイベントの行番号など、すぐに利用できる診断情報を含んでいます。
- 含まれているモジュールにログインしたイベントは、フィルタリングしない限り、ルートロガーからアプリケーションのロギングストリームに自動的にアクセスできます。
- ロギングは、
logging.Logger.setLevel()
メソッドを使用することによって選択的に消音することができます。または、属性logging.Logger.disabled
をTrue
に設定することによって無効にすることができます。
ライブラリのロギング¶
ライブラリのログを設定する ときの注意は ロギングチュートリアル にあります。 ライブラリーではなく user がロギング・イベントが発生したときに何が起こるかを指示する必要があるため、1つの警告は繰り返されます。
注釈
NullHandler以外のハンドラをライブラリのロガーに追加しないことを強くお勧めします。
ライブラリ内のロガーをインスタンス化する際のベストプラクティスは、グローバル変数 __name__
を使用してロガーを作成することです。logging
モジュールはドット表記を使用してロガーの階層を作成するので、__name__
を使用すると名前が衝突しないと保証されます。
ここでは、 requests source からのベストプラクティスの例を示します。 - これをあなたの __init__.py
に置きます。
# Set default logging handler to avoid "No handler found" warnings.
import logging
try: # Python 2.7+
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass
logging.getLogger(__name__).addHandler(NullHandler())
アプリケーションへのログイン¶
twelve factor app は、アプリケーション開発における優れた実践の権威ある参考資料で、 logging best practice のセクションを含んでいます。ログイベントをイベントストリームとして扱い、イベントストリームを標準出力に送信してアプリケーション環境で処理することを強調しています。
ロガーを設定するには、少なくとも3つの方法があります:
- INI形式のファイルを使用する:
- Pro:
logging.config.listen()
関数を使って実行中に設定を更新することができます。 - Con: ロガーをコードで設定するときほど、(たとえば、カスタムサブクラスのフィルターやロガーのようには)細かく制御できません。
- Pro:
- 辞書またはJSON形式のファイルを使用する:
- Pro: 実行中に更新することに加えて、Python 2.6から標準ライブラリに
json
モジュールを使用してファイルからロードすることができます。 - Con: コードでロガーを設定するときほど細かく制御できません。
- Pro: 実行中に更新することに加えて、Python 2.6から標準ライブラリに
- コードを使う:
- Pro: 設定を完全に制御します。
- Con: 変更にはソースコードを変更する必要があります。
INIファイルによる設定例¶
ファイルの名前が logging_config.ini
であるとしましょう。 ファイル形式の詳細は、 ロギングチュートリアル の logging configuration セクションにあります。
[loggers]
keys=root
[handlers]
keys=stream_handler
[formatters]
keys=formatter
[logger_root]
level=DEBUG
handlers=stream_handler
[handler_stream_handler]
class=StreamHandler
level=DEBUG
formatter=formatter
args=(sys.stderr,)
[formatter_formatter]
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
次に、コードに logging.config.fileConfig()
を使用します:
import logging
from logging.config import fileConfig
fileConfig('logging_config.ini')
logger = logging.getLogger()
logger.debug('often makes a very good meal of %s', 'visiting tourists')
辞書による設定例¶
Python 2.7では、設定の詳細を持つ辞書を使用できます。 PEP 391 は、構成辞書の必須要素とオプション要素のリストを含んでいます。
import logging
from logging.config import dictConfig
logging_config = dict(
version = 1,
formatters = {
'f': {'format':
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s'}
},
handlers = {
'h': {'class': 'logging.StreamHandler',
'formatter': 'f',
'level': logging.DEBUG}
},
root = {
'handlers': ['h'],
'level': logging.DEBUG,
},
)
dictConfig(logging_config)
logger = logging.getLogger()
logger.debug('often makes a very good meal of %s', 'visiting tourists')
コードの直接の構成例¶
import logging
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
logger.debug('often makes a very good meal of %s', 'visiting tourists')
共通の落とし穴¶
ほとんどの場合、Pythonは驚きを避けるきれいで一貫した言語を目指しています。 しかし、新入社員を混乱させる可能性のあるケースがいくつかあります。
これらのケースのいくつかは意図的ですが、潜在的に驚くことでしょう。 間違いなく、言語の欠点と見なすこともできます。 一般的には、一見すると奇妙に見える可能性のあるトリッキーな動作の集合ですが、驚きの根底にある原因を認識すると一般的には賢明です。
変更可能なデフォルト引数¶
おそらく新しいPythonプログラマが遭遇する最も驚くべき点は、関数定義におけるデフォルトの引数を変更できるPythonの扱いです。
あなたが書いたもの¶
def append_to(element, to=[]):
to.append(element)
return to
起こることが予想されること¶
my_list = append_to(12)
print my_list
my_other_list = append_to(42)
print my_other_list
2番目の引数が指定されていない場合、関数が呼び出されるたびに新しいリストが作成され、出力は次のようになります。
[12] [42]
何が起こるか¶
[12]
[12, 42]
関数が定義されているときに新しいリストが作成され、各リスト内で連続して同じリストが使用されます。
Pythonのデフォルト引数は、関数が定義されているときに評価されます。関数が呼び出されるたびに(例えば、Rubyのように)評価されるのではありません。 つまり、変更可能なデフォルトの引数を使用してそれを変更すると、その関数への今後のすべての呼び出しのためにそのオブジェクトを変更してしまいます。
代わりに何をすべきか¶
関数が呼び出されるたびに、デフォルトの引数を使用して引数が指定されていないことを伝える (None
はしばしば良い選択です) 新しいオブジェクトを作成します。
def append_to(element, to=None):
if to is None:
to = []
to.append(element)
return to
落とし穴が落とし穴でないとき¶
場合によっては、関数の呼び出し間で状態を維持するために、この動作を具体的に「悪用する」(読み込み:意図したとおりに使用する)ことができます。 これは、キャッシング機能を記述するときによく行われます。
遅延バインディングクロージャ¶
混乱のもう一つの一般的な原因は、Pythonがクロージャー(またはその周囲のグローバルスコープ)で変数をバインドする方法です。
あなたが書いたもの¶
def create_multipliers():
return [lambda x : i * x for i in range(5)]
起こることが予想されること¶
for multiplier in create_multipliers():
print multiplier(2)
引数を掛け合わせる独自のクローズドオーバー i
変数を持つ5つの関数を含むリストです:
0
2
4
6
8
何が起こるか¶
8
8
8
8
8
5つの関数が作成されます。 代わりにそれらのすべてが x
を4倍します。
Pythonのクロージャは late binding です。 これは、内部関数が呼び出された時点でクロージャーで使用される変数の値が参照されることを意味します。
ここで、返される関数の any が呼び出されるたびに、呼び出し時に i
の値が周囲のスコープで参照されます。 それまでにループが完了し、最終値が4のままの i
が残されます。
この問題について特に厄介なのは、これが何かと関係していると思われる誤った情報です lambdas lambda
式で作成された関数は決して特別なものではなく、実際には普通の def
を使うだけで同じ正確な振る舞いが現れます:
def create_multipliers():
multipliers = []
for i in range(5):
def multiplier(x):
return i * x
multipliers.append(multiplier)
return multipliers
代わりに何をすべきか¶
最も一般的な解決策は間違いなくハックのビットです。 関数へのデフォルト引数の評価に関するPythonの前述の動作 (default_args を参照) のために、デフォルト引数を使用してその引数にすぐにバインドするクロージャを作成することができます:
def create_multipliers():
return [lambda x, i=i : i * x for i in range(5)]
代わりに、functools.partial関数を使用することもできます:
from functools import partial
from operator import mul
def create_multipliers():
return [partial(mul, i) for i in range(5)]
落とし穴が落とし穴でないとき¶
場合によっては、クロージャーがこのように動作することを望みます。 最近のバインディングは、多くの状況で良好です。 ユニークな機能を作り出すためのループは、残念ながら、しゃっくりを引き起こす可能性があります。
どこでもバイトコード (.pyc) ファイル!¶
デフォルトでは、ファイルからPythonコードを実行すると、Pythonインタプリタは自動的にそのファイルのバイトコードバージョンをディスクに書き込みます。 module.pyc
。
これらの .pyc
ファイルはあなたのソースコードリポジトリにチェックインされるべきではありません。
理論的には、パフォーマンス上の理由から、この動作は既定でオンになっています。 これらのバイトコードファイルがなければ、Pythonはファイルが読み込まれるたびにバイトコードを再生成します。
- バイトコード (.pyc) ファイルの無効化
幸いにも、バイトコードを生成するプロセスは非常に高速であり、コードを開発する際に心配する必要はありません。
それらのファイルは迷惑なので、取り除いてみましょう!
$ export PYTHONDONTWRITEBYTECODE=1
$PYTHONDONTWRITEBYTECODE
環境変数を設定すると、Pythonはこれらのファイルをディスクに書き込まなくなり、開発環境はきれいになります。
あなたの ~/.profile
にこの環境変数を設定することをお勧めします。
ライセンスの選択¶
あなたのソースの出版物はライセンスが 必要 です。米国では、ライセンスが指定されていない場合、ユーザーはダウンロード、変更、または配布する権利がありません。さらに、どのルールを使用するかを指定しない限り、コードに貢献することはできません。ライセンスを選択するのは複雑なので、ここでいくつか指摘しておきます。
オープンソース。 選択できる オープンソースライセンス はたくさんあります 。
一般に、これらのライセンスは次の2つのカテゴリのいずれかに分類されます。
- ユーザーが自由に自由に行うことができるように、より自由になるようにするライセンス(これは、MIT、BSD、およびApacheなどのよりオープンなオープンソースライセンスです)。
- GPLやLGPLなどの自由ソフトウェアライセンスの許容度が低いため、コード自体が変更され、それに伴って配布されることを含めて、常にコード自体が無料であることを確認することに重点を置いたライセンス。
後者は、誰かがソフトウェアにコードを追加したり、変更のソースコードを含めずにコードを配布することを許可しないという意味では、あまり許されていません。
あなたのプロジェクトに適したものを選ぶのを助けるために、 license chooser があり、それを使ってください。
もっと許容的な
- PSFL(Python Software Foundation License) - Python自体に貢献するためのもの
- MIT / BSD / ISC
- MIT (X11)
- New BSD
- ISC
- Apache
あまり許容しない
- LGPL
- GPL
- GPLv2
- GPLv3
特定のソフトウェアを使って何ができるか、できないか、また何をしなければならないのかを説明したライセンスの概要は tl; drLegal にあります。
Python アプリケーションのシナリオガイド¶
本書のこのパートは、さまざまなシナリオに基づいたツールとモジュールのアドバイスに焦点を当てています。
ネットワークアプリケーション¶
HTTP¶
ハイパーテキスト転送プロトコル(HTTP)は、分散された共同のハイパーメディア情報システムのアプリケーションプロトコルです。 HTTPはWorld Wide Webのデータ通信の基盤です。
Requests¶
Pythonの標準urllib2モジュールは必要なHTTP機能のほとんどを提供しますが、APIは完全に壊れています。 これは、異なる時間と異なるウェブのために作られました。最も単純なタスクを実行するには、膨大な作業(メソッドのオーバーライドさえ)が必要です。
RequestsはPython HTTPからすべての作業を取り除き、Webサービスとの統合をシームレスにします。 クエリ文字列をURLに手動で追加したり、POSTデータをフォームエンコードする必要はありません。 キープアライブとHTTP接続ポーリングは、リクエスト内に埋め込まれたurllib3によって100%自動化されます。
分散システム¶
ZeroMQ¶
ØMQ(スペルのあるZeroMQ、0MQ、またはZMQ)は、スケーラブルな分散アプリケーションまたは並行アプリケーションでの使用を目的とした高性能非同期メッセージングライブラリです。 メッセージキューを提供しますが、メッセージ指向のミドルウェアとは異なり、専用メッセージブローカなしでØMQシステムを実行できます。 ライブラリは使い慣れたソケットスタイルのAPIを持つように設計されています。
RabbitMQ¶
RabbitMQは、AMQP(Advanced Message Queuing Protocol)を実装したオープンソースのメッセージブローカーソフトウェアです。 RabbitMQサーバーはErlangプログラミング言語で書かれており、クラスタリングとフェールオーバーのためにOpen Telecom Platformフレームワーク上に構築されています。 ブローカとのインターフェイスをとるクライアントライブラリは、すべての主要なプログラミング言語で使用できます。
Webアプリケーション¶
高速プロトタイプと大きなプロジェクトの両方に対応した強力なスクリプト言語として、PythonはWebアプリケーション開発に広く使用されています。
コンテキスト¶
WSGI¶
Webサーバーゲートウェイインターフェイス(略して “WSGI” )は、WebサーバーとPython Webアプリケーションフレームワークの間の標準インターフェイスです。 WSGI準拠のWebサーバ をWebサーバやPythonのWebフレームワークとの間に動作し、通信を標準化することで、WSGIはいずれにも展開することができる携帯用のPythonのWebコードを記述することが可能となります。 WSGIは、pep:3333 に記載されています。
フレームワーク¶
大まかに言えば、Webフレームワークは、一連のライブラリとメインハンドラで構成され、その中にWebアプリケーション(つまり、インタラクティブなWebサイト)を実装するためのカスタムコードを作成できます。 ほとんどのWebフレームワークには、少なくとも以下を達成するためのパターンとユーティリティが含まれています。
- URLルーティング
- 着信するHTTP要求を特定のPythonコードに一致させて呼び出します
- 要求オブジェクトと応答オブジェクト
- ユーザーのブラウザから受信した情報またはユーザーのブラウザに送信した情報をカプセル化する
- テンプレートエンジン
- アプリケーションのロジックを実装するPythonコードを、それが生成するHTML(またはその他の)出力から分離することを可能にする
- 開発用Webサーバ
- 迅速な開発を可能にするために開発マシン上でHTTPサーバーを実行します。 ファイルが更新されると自動的にサーバー側のコードがリロードされる
Django¶
Django は、 “バッテリー同梱” Webアプリケーションフレームワークであり、コンテンツ指向のウェブサイトを作成するための優れた選択肢です。 Djangoは、多くのユーティリティとパターンを提供することにより、複雑なデータベースベースのWebアプリケーションを迅速に構築し、それを使用して作成されたコードのベストプラクティスを奨励することを目指しています。
Djangoには大きくて活動的なコミュニティがあり、あなたのニーズに合わせてカスタマイズされた新しいプロジェクトに組み込むことができる、多くのあらかじめ構築された 再利用可能なモジュール があります。
毎年Djangoカンファレンスが 米国 と 欧州 で開催されています。
今日の新しいPython Webアプリケーションの大部分は、Djangoで構築されています。
Flask¶
Flask はPythonの “マイクロフレームワーク” であり、小さなアプリケーション、API、およびWebサービスの構築に最適です。
Flaskを使ってアプリケーションをビルドするのは、標準のPythonモジュールを書くのと似ていますが、いくつかの関数にはルートが付けられています。 それは本当に美しいです。
おそらく必要なものをすべて提供することを目指すのではなく、URLルーティング、リクエストとレスポンスオブジェクト、テンプレートなど、Webアプリケーションフレームワークの中で最も一般的に使用されるコアコンポーネントを実装します。
Flaskを使用している場合は、アプリケーションの他のコンポーネントがあればそれを選択する必要があります。 たとえば、データベースへのアクセスやフォームの生成と検証は、Flaskの組み込み関数ではありません。
多くのWebアプリケーションにはこれらの機能が必要ないので、これは素晴らしいことです。 そういう人には、あなたのニーズに合った Extensions がたくさんあります。 または、あなたが望む任意のライブラリを簡単に使用できます。
Flaskは、Djangoには適していないPython Webアプリケーションのデフォルトの選択です。
Web Servers¶
WSGI Servers¶
スタンドアロンのWSGIサーバーは、通常、従来のWebサーバーよりも少ないリソースを使用し、最高のパフォーマンス [3] を提供します。
Gunicorn¶
Gunicorn (Green Unicorn) はPythonアプリケーションを提供するために使われる純粋なPythonのWSGIサーバーです。 他のPython Webサーバーとは異なり、思慮深いユーザーインターフェイスがあり、使いやすく構成が簡単です。
Gunicornは、構成に対して正気で合理的なデフォルトを持っています。 しかし、uWSGIのような他のサーバーは、大幅にカスタマイズ可能であるため、効果的に使用するのがはるかに困難です。
Gunicornは今日の新しいPython Webアプリケーションの推奨選択肢です。
Waitress¶
Waitress は、”非常に許容可能なパフォーマンス” を主張する純粋なpython WSGIサーバーです。 そのドキュメントはあまり詳細ではありませんが、Gunicornにはない優れた機能(HTTPリクエストバッファリングなど)があります。
WaitressはPython Web開発コミュニティで人気を博しています。
uWSGI¶
uWSGI は、ホスティングサービスを構築するための完全なスタックです。 プロセス管理、プロセス監視、およびその他の機能に加えて、uWSGIは、PythonやWSGIなど、さまざまなプログラミング言語とプロトコルのアプリケーションサーバーとして機能します。 uWSGIは、スタンドアロンのWebルーターとして実行することも、完全なWebサーバー(NginxやApacheなど)の背後で実行することもできます。 後者の場合、WebサーバーはuWSGIとアプリケーションの操作を uwsgi protocol で設定できます。 uWSGIのWebサーバーサポートにより、Pythonを動的に構成し、環境変数を渡し、さらにチューニングすることができます。 詳細については、 uWSGIマジック変数 を参照してください。
なぜ必要なのか分からない限り、私はuWSGIの使用をお勧めしません。
サーバーのベストプラクティス¶
現在ホストされているPythonアプリケーションの大部分は、 nginx のような軽量のWebサーバーの後ろにある Gunicorn のようなWSGIサーバーでホストされています。
WSGIサーバーはPythonアプリケーションを処理しますが、Webサーバーは静的ファイルサービス、要求ルーティング、DDoS保護、基本認証など、より適切なタスクを処理します。
ホスティング¶
PaaS(Platform-as-a-Service)は、Webアプリケーションのインフラストラクチャ、ルーティング、およびスケーリングを抽象化して管理するクラウドコンピューティングインフラストラクチャの一種です。 PaaSを使用する場合、アプリケーション開発者はデプロイの詳細を意識する必要はなく、アプリケーションコードの作成に専念することができます。
Heroku¶
Heroku はPython 2.7-3.5アプリケーションのための一流のサポートを提供します。
Herokuは、あらゆる種類のPython Webアプリケーション、サーバー、およびフレームワークをサポートしています。 アプリケーションは無料でHerokuで開発することができます。 アプリケーションの本稼働準備が整ったら、趣味やプロフェッショナルアプリケーションにアップグレードできます。
Herokuは、PythonとHerokuを使用した 詳細な記事 と、 ステップバイステップの手順 最初のアプリケーションの設定方法について説明します。
Herokuは、今日のPython Webアプリケーションの展開に推奨されるPaaSです。
Eldarion¶
Eldarion (正式にGondorとして知られています) は、Kubernetes、CoreOS、およびDockerによるPaaSです。彼らはどんなWSGIアプリケーションもサポートしており、 Django projects の導入に関するガイドを持っています。
テンプレート¶
ほとんどのWSGIアプリケーションは、HTMLや他のマークアップ言語でコンテンツを提供するためにHTTP要求に応答しています。 Pythonから直接テキストコンテンツを生成するのではなく、懸念を分離するという概念は、テンプレートを使用するように私たちに助言します。テンプレートエンジンは、不必要な繰り返しを避けるための階層と包含のシステムを備えたテンプレートファイル群を管理し、実際のコンテンツのレンダリング(生成)を担当し、テンプレートの静的コンテンツをアプリケーションによって生成された動的コンテンツです。
テンプレートファイルはデザイナーやフロントエンドの開発者によって書き込まれることがあるため、増えていく複雑さに対応することは困難です。
一般的な良い方法は、動的コンテンツをテンプレートエンジンやテンプレート自体に渡すアプリケーションの部分に適用されます。
- テンプレートファイルには、テンプレートのレンダリングに必要な動的コンテンツのみが渡されます。 「念のため」に追加のコンテンツを渡すような誘惑を避けてください。未使用の変数を後で削除するよりも必要なときに不足している変数を追加する方が簡単です。
- 多くのテンプレートエンジンでは、テンプレート自体に複雑なステートメントや割り当てが可能であり、多くの場合、テンプレートでPythonコードを評価できるものが多数あります。 この利便性は、制御されていない複雑さの増加につながり、しばしばバグを見つけにくくします。
- JavaScriptテンプレートとHTMLテンプレートを混在させる必要があることがよくあります。 この設計に対する単純なアプローチは、HTMLテンプレートがいくつかの可変コンテンツをJavaScriptコードに渡す部分を分離することです。
Jinja2¶
Jinja2 は非常によく評価されているテンプレートエンジンです。
これは、テキストベースのテンプレート言語を使用するので、HTMLだけでなく、あらゆるタイプのマークアップを生成するために使用できます。 これは、フィルタ、タグ、テスト、およびグローバルのカスタマイズを可能にします。 これは、Djangoのテンプレートシステムよりも多くの改善点があります。
ここでJinja2の重要なHTMLタグ:
{# This is a comment #}
{# The next tag is a variable output: #}
{{title}}
{# Tag for a block, can be replaced through inheritance with other html code #}
{% block head %}
<h1>This is the head!</h1>
{% endblock %}
{# Output of an array as an iteration #}
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
次の一覧は、Tornado Webサーバーと組み合わせたWebサイトの例です。 Tornadoはそれほど複雑ではありません。
# import Jinja2
from jinja2 import Environment, FileSystemLoader
# import Tornado
import tornado.ioloop
import tornado.web
# Load template file templates/site.html
TEMPLATE_FILE = "site.html"
templateLoader = FileSystemLoader( searchpath="templates/" )
templateEnv = Environment( loader=templateLoader )
template = templateEnv.get_template(TEMPLATE_FILE)
# List for famous movie rendering
movie_list = [[1,"The Hitchhiker's Guide to the Galaxy"],[2,"Back to future"],[3,"Matrix"]]
# template.render() returns a string which contains the rendered html
html_output = template.render(list=movie_list,
title="Here is my favorite movie list")
# Handler for main page
class MainHandler(tornado.web.RequestHandler):
def get(self):
# Returns rendered template string to the browser request
self.write(html_output)
# Assign handler to the server root (127.0.0.1:PORT/)
application = tornado.web.Application([
(r"/", MainHandler),
])
PORT=8884
if __name__ == "__main__":
# Setup the server
application.listen(PORT)
tornado.ioloop.IOLoop.instance().start()
base.html
ファイルは、例えばコンテンツブロックに実装されているすべてのサイトページのベースとして使用できます。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="style.css" />
<title>{{title}} - My Webpage</title>
</head>
<body>
<div id="content">
{# In the next line the content from the site.html template will be added #}
{% block content %}{% endblock %}
</div>
<div id="footer">
{% block footer %}
© Copyright 2013 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
次のリストは、 base.html
を拡張したPythonアプリケーションにロードされたサイトページ (site.html
) です。 コンテンツブロックは base.html
ページの対応するブロックに自動的に設定されます。
<!{% extends "base.html" %}
{% block content %}
<p class="important">
<div id="content">
<h2>{{title}}</h2>
<p>{{ list_title }}</p>
<ul>
{% for item in list %}
<li>{{ item[0]}} : {{ item[1]}}</li>
{% endfor %}
</ul>
</div>
</p>
{% endblock %}
Jinja2は、新しいPython Webアプリケーション用に推奨されるテンプレートライブラリです。
Chameleon¶
Chameleon ページテンプレートは、HTML/XMLテンプレートエンジンの Template Attribute Language (TAL) の実装です。 TAL式構文 (TALES) 、 マクロ展開TAL (Metal) シンタックス。
ChameleonはPython 2.5以降(3.xやpypyを含む)で利用可能で、 Pyramid Framework で一般的に使用されています。
ページテンプレートは、ドキュメント構造内に特別な要素属性とテキストマークアップを追加します。 単純な言語構造のセットを使用して、文書の流れ、要素の繰り返し、テキストの置換と翻訳を制御します。 属性ベースの構文のため、未レンダリングページテンプレートは有効なHTMLであり、ブラウザで表示したり、WYSIWYGエディタで編集することもできます。 これにより、デザイナーとの往復のコラボレーションや、ブラウザ内の静的ファイルによるプロトタイプ作成が容易になります。
基本的なTAL言語は、例を理解するのに十分シンプルです:
<html>
<body>
<h1>Hello, <span tal:replace="context.name">World</span>!</h1>
<table>
<tr tal:repeat="row 'apple', 'banana', 'pineapple'">
<td tal:repeat="col 'juice', 'muffin', 'pie'">
<span tal:replace="row.capitalize()" /> <span tal:replace="col" />
</td>
</tr>
</table>
</body>
</html>
テキストを挿入するための <span tal:replace=”expression” /> パターンは、未翻訳のテンプレートで厳密な妥当性を必要としない場合は、パターンを使用するより簡潔で読みやすい構文で置き換えることができます。 ${expression} を以下のように定義します。
<html>
<body>
<h1>Hello, ${world}!</h1>
<table>
<tr tal:repeat="row 'apple', 'banana', 'pineapple'">
<td tal:repeat="col 'juice', 'muffin', 'pie'">
${row.capitalize()} ${col}
</td>
</tr>
</table>
</body>
</html>
しかし、完全な <span tal:replace=”expression”>Default Text</span> の構文では、未レンダリングテンプレートのデフォルトコンテンツも使用できることに注意してください。
Pyramidの世界からのもので、Chameleonは広く使われていません。
Mako¶
Mako はパフォーマンスを最大限に高めるためにPythonにコンパイルするテンプレート言語です。 その構文とapiは、DjangoやJinja2テンプレートのような他のテンプレート言語の最良の部分から借用されています。 これは Pylons and Pyramid Webフレームワークに含まれるデフォルトのテンプレート言語です。
Makoのテンプレートの例は次のようになります:
<%inherit file="base.html"/>
<%
rows = [[v for v in range(0,10)] for row in range(0,10)]
%>
<table>
% for row in rows:
${makerow(row)}
% endfor
</table>
<%def name="makerow(row)">
<tr>
% for name in row:
<td>${name}</td>\
% endfor
</tr>
</%def>
非常に基本的なテンプレートをレンダリングするには、次のようにします:
from mako.template import Template
print(Template("hello ${data}!").render(data="world"))
MakoはPythonのWebコミュニティで尊敬されています。
References
[1] | The mod_python project is now officially dead |
[2] | mod_wsgi vs mod_python |
[3] | Benchmark of Python WSGI Servers |
HTMLスクレイピング¶
Webスクレイピング¶
WebサイトはHTMLを使用して書かれています。つまり、各Webページは構造化文書です。時には、それらからいくつかのデータを取得し、私たちがその間に構造を保存することは素晴らしいことでしょう。 Webサイトは、 csv
や json
などの快適な形式でデータを提供するとは限りません。
Webスクレイピングは、コンピュータプログラムを使用してWebページを調べ、必要なデータを、同時にデータの構造を保持しながら、最も便利な形式で収集するプラクティスです。
lxml と Requests¶
lxml はXMLやHTML文書を非常に素早く解析するために書かれた非常に広範囲なライブラリです。 また、速度と可読性が向上したため、すでに組み込まれているurllib2モジュールの代わりに Requests モジュールも使用します。 pip install lxml
と pip install requests
の両方を使って簡単にインストールできます。
インポートから始めましょう:
from lxml import html
import requests
次に、 requests.get
を使ってデータを含むウェブページを取得し、 html
モジュールを使って解析し、結果を tree
に保存します:
page = requests.get('http://econpy.pythonanywhere.com/ex/001.html')
tree = html.fromstring(page.content)
( page.text
ではなく page.content
を使用する必要があります。なぜなら、 html.fromstring
は入力として bytes
を暗黙的に期待しているからです。)
tree
にはHTMLファイル全体がツリー構造で表示され、XPathとCSSSelectの2通りの方法があります。この例では、前者に焦点を当てます。
XPathは、HTMLやXML文書などの構造化文書に情報を配置する方法です。 XPathの良い紹介は、 W3Schools です。
FireBug for FirefoxやChrome Inspectorなどの要素のXPathを取得するためのさまざまなツールもあります。 Chromeを使用している場合は、要素を右クリックして 要素を検査 を選択し、コードを強調表示してもう一度右クリックし、 XPathのコピー を選択します。
簡単な分析の結果、このページのデータは2つの要素に分かれています.1つはdivというタイトルで、 buyer-name という名前のクラスと item-price というクラスのスパンです。
<div title="buyer-name">Carson Busses</div>
<span class="item-price">$29.95</span>
これを知ることで、正しいXPathクエリを作成し、lxmlの xpath
関数を以下のように使用することができます:
#This will create a list of buyers:
buyers = tree.xpath('//div[@title="buyer-name"]/text()')
#This will create a list of prices
prices = tree.xpath('//span[@class="item-price"]/text()')
私たちが正確に何を得たかを見てみましょう:
print 'Buyers: ', buyers
print 'Prices: ', prices
Buyers: ['Carson Busses', 'Earl E. Byrd', 'Patty Cakes',
'Derri Anne Connecticut', 'Moe Dess', 'Leda Doggslife', 'Dan Druff',
'Al Fresco', 'Ido Hoe', 'Howie Kisses', 'Len Lease', 'Phil Meup',
'Ira Pent', 'Ben D. Rules', 'Ave Sectomy', 'Gary Shattire',
'Bobbi Soks', 'Sheila Takya', 'Rose Tattoo', 'Moe Tell']
Prices: ['$29.95', '$8.37', '$15.26', '$19.25', '$19.25',
'$13.99', '$31.57', '$8.49', '$14.47', '$15.86', '$11.11',
'$15.98', '$16.27', '$7.50', '$50.85', '$14.26', '$5.68',
'$15.00', '$114.07', '$10.09']
おめでとう! lxmlとRequestsを使用して、Webページから必要なすべてのデータを正常に削除しました。 私たちはそれを2つのリストとしてメモリに格納しています。 今では、あらゆる種類のクールなことを行うことができます。Pythonを使用して解析するか、ファイルに保存して世界と共有できます。
このスクリプトを修正して、このサンプルデータセットの残りのページを繰り返したり、このアプリケーションを書き直してスレッドを使用して速度を向上させたりすることも考えられます。
コマンドラインアプリケーション¶
Console Application とも呼ばれるコマンドラインアプリケーションは、 shell コマンドラインアプリケーションは通常、さまざまな入力を引数として受け入れます。多くの場合、パラメータやサブコマンド、オプション(フラグやスイッチと呼ばれることが多い)と呼ばれます。
いくつかの一般的なコマンドラインアプリケーションには次のものがあります。
- Grep - プレーンテキストのデータ検索ユーティリティ
- curl - URL構文によるデータ転送のためのツール
- httpie - ユーザーフレンドリーなコマンドラインHTTPクライアント。
- git - 分散バージョン管理システム
- mercurial - 主にPythonで書かれた分散バージョン管理システム
Clint¶
clint は、コマンドラインアプリケーションを開発するための非常に便利なツールで埋め尽くされたPythonモジュールです。 それは以下のような機能をサポートしています。 CLIの色とインデント、シンプルで強力な列プリンタ、イテレータベースのプログレスバー、暗黙的な引数処理。
Click¶
click は、可能な限り小さなコードで構成可能な方法でコマンドラインインターフェイスを作成するためのPythonパッケージです。 この「Command-Line Interface Creation Kit」は高度に設定可能ですが、デフォルトですぐに適切なデフォルトが提供されます。
Plac¶
Plac はPythonの標準ライブラリ argparse の単純なラッパーで、宣言的インタフェースを使用して複雑さの大部分を隠します。引数パーザは、命令的に記述されるのではなく推論されます。このモジュールは、素朴なユーザー、プログラマー、システム管理者、科学者、一般的にはスローアウェイスクリプトを作成し、迅速かつ簡単なコマンドラインインターフェイスを作成することを目指しています。
GUIアプリケーション¶
GUIアプリケーションのアルファベット順のリスト
Camelot¶
Camelot は、Python、SQLAlchemy、Qtの上にアプリケーションを構築するためのコンポーネントを提供します。これはDjangoの管理インターフェースに触発されています。
情報の主なリソースは、Webサイトです。 http://www.python-camelot.com メーリングリスト https://groups.google.com/forum/#!forum/project-camelot
Cocoa¶
注釈
CocoaフレームワークはOS Xでのみ利用可能です。クロスプラットフォームアプリケーションを作成しているなら、これを選択しないでください!
GTk¶
PyGTKは、GTK +ツールキット用のPythonバインディングを提供します。 GTK +ライブラリ自体と同様に、現在GNU LGPLのライセンスを受けています。 PyGTKが現在Gtk-2.X API(Gtk-3.0ではない)だけをサポートしていることは注目に値します。 PyGTKを新しいプロジェクトに使用しないこと、そして既存のアプリケーションをPyGTKからPyGObjectに移植することが現在推奨されています。
PyGObject aka (PyGi)¶
PyGObject はPythonバインディングを提供し、GNOMEソフトウェアプラットフォーム全体にアクセスできます。 これはGTK + 3と完全に互換性があります。ここでは、 Python GTK + 3チュートリアル を始めるためのチュートリアルです。
Kivy¶
Kivy は、マルチタッチ対応のメディアリッチアプリケーションの開発のためのPythonライブラリです。 目的は、コードを再利用可能かつ展開可能にすると同時に、迅速かつ簡単なインタラクションの設計と迅速なプロトタイプ作成を可能にすることです。
KivyはOpenGLベースのPythonで書かれており、マウス、デュアルマウス、TUIO、WiiMote、WM_TOUCH、HIDtouch、Appleの製品などさまざまな入力デバイスをサポートしています。
Kivyはコミュニティによって積極的に開発されており、自由に使用できます。 すべての主要なプラットフォーム(Linux、OSX、Windows、Android)で動作します。
情報の主なリソースは、Webサイト http://kivy.org です。
PyObjC¶
注釈
OS Xでのみ利用可能です。クロスプラットフォームアプリケーションを作成する場合は、これを選択しないでください。
PySide¶
PySideは、クロスプラットフォームのGUIツールキットQtのPythonバインディングです。
pip install pyside
https://wiki.qt.io/Category:LanguageBindings::PySide::Downloads
PyjamasDesktop (pyjs Desktop)¶
PyjamasDesktopはPyjamasの一部です。 PyjamasDesktopは、デスクトップとクロスプラットフォームのフレームワーク用に設定されたアプリケーションウィジェットです。 (リリース後v0.6 PyjamasDesktopはPyjamas(Pyjs)の一部です)。 簡単に言えば、完全に同じPython Webアプリケーションソースコードをスタンドアロンのデスクトップアプリケーションとして実行することができます。
Python Wiki for PyjamasDesktop.
メインのウェブサイト; pyjs Desktop 。
Tk¶
Tkinterは、Tcl/Tkの上にある薄いオブジェクト指向のレイヤーです。 Python標準ライブラリに含まれているという利点があり、もっとも便利で互換性のあるツールキットです
TkとTkinterの両方は、ほとんどのUnixプラットフォームやWindowsとMacintoshシステムで利用できます。 8.0リリースから、Tkはすべてのプラットフォームでネイティブのルック・アンド・フィールを提供します。
TkDocs にPythonの例を載せた良い多言語Tkチュートリアルがあります。 Python Wiki にはより多くの情報があります。
wxPython¶
wxPythonはPythonプログラミング言語用のGUIツールキットです。 Pythonプログラマーは、堅牢で高機能なグラフィカルユーザーインターフェイスを持つプログラムを簡単かつ簡単に作成することができます。 これは、C ++で書かれた人気のあるwxWidgetsクロスプラットフォームのGUIライブラリをラップするPython拡張モジュール(ネイティブコード)として実装されています。
インストール(安定版)wxPython http://www.wxpython.org/download.php#stable にアクセスして、ご使用のOSに適したパッケージをダウンロードしてください。
データベース¶
DB-API¶
Python Database API(DB-API)は、Pythonデータベースアクセスモジュール用の標準インタフェースを定義します。それは PEP 249 に書かれています。 sqlite3 、psycopg 、 mysql-python のようなほぼすべてのPythonデータベースモジュールは、このインターフェースに準拠しています。
SQLAlchemy¶
SQLAlchemy は、よく使われるデータベースツールキットです。 多くのデータベースライブラリとは異なり、ORMレイヤーを提供するだけでなく、SQLを使用せずにデータベースに依存しないコードを記述するための一般化されたAPIも提供します。
$ pip install sqlalchemy
Records¶
Records は、生のSQLクエリをさまざまなデータベースに送るために設計された、最小限のSQLライブラリです。 データはプログラムで使用することも、多数の有用なデータ形式にエクスポートすることもできます。
$ pip install records
SQLデータをエクスポートするためのコマンドラインツールも含まれています。
Django ORM¶
Django ORMはデータベースアクセスを提供するために Django によって使用されるインタフェースです。
これは models の考え方に基づいています。これは、Pythonでデータを操作しやすくするための抽象です。
基本:
- 各モデルは、django.db.models.Modelをサブクラス化するPythonクラスです。
- モデルの各属性は、データベースフィールドを表します。
- Djangoは自動的に生成されたデータベースアクセスAPIを提供します。 クエリーの作成 を参照してください。
peewee¶
peewee は、デフォルトでSQLite、MySQL、PostgresをサポートするPython 2.6+と3.2+をサポートする軽量化に重点を置いた別のORMです。 model layer はDjango ORMと似ており、 SQLのようなメソッド を使用してデータを照会します。 SQLite、MySQL、Postgresはすぐにサポートされていますが、 アドオンのコレクション 利用可能です。
ネットワーキング¶
Twisted¶
Twisted は、イベント駆動型のネットワーキングエンジンです。 httpサーバやクライアント、SMTP、POP3、IMAP、SSHプロトコルを使用するアプリケーション、インスタントメッセージング、さらに多く を含みます。
PyZMQ¶
PyZMQ は、高性能非同期メッセージングライブラリである ZeroMQ のPythonバインディングです。 ZeroMQの大きな利点の1つは、メッセージブローカなしでメッセージキューに使用できることです。 これの基本的なパターンは次のとおりです。
- リクエスト-リプライ: 一連のクライアントを一連のサービスに接続します。 これは、リモートプロシージャコールおよびタスク配布パターンです。
- パブリッシュ-サブスクライブ: 一連のパブリッシャを一連のサブスクライバに接続します。 これはデータ配布パターンです。
- プッシュプル(またはパイプライン): ファンアウト/ファンインパターンで複数のステップとループを持つことができるノードを接続します。 これは、並行タスク配布および収集パターンです。
クイックスタートについては、 ZeroMQ guide を読んでください。
システム管理¶
Fabric¶
Fabric は、システム管理作業を簡素化するためのライブラリです。 ChefとPuppetはサーバやシステムライブラリの管理に専念する傾向がありますが、Fabricはデプロイメントなどのアプリケーションレベルのタスクにもっと重点を置いています。
Install Fabric:
$ pip install fabric
次のコードは、 memory_usage
と deploy
の2つのタスクを作成します。 前者は各マシンでメモリ使用量を出力します。 後者は各サーバにsshし、プロジェクトディレクトリにcdし、仮想環境を有効にし、最新のコードベースを取得して、アプリケーションサーバを再起動します。
from fabric.api import cd, env, prefix, run, task
env.hosts = ['my_server1', 'my_server2']
@task
def memory_usage():
run('free -m')
@task
def deploy():
with cd('/var/www/project-env/project'):
with prefix('. ../bin/activate'):
run('git pull')
run('touch app.wsgi')
以前のコードを fabfile.py
という名前のファイルに保存すると、次のようにメモリ使用量を確認できます。
$ fab memory_usage
[my_server1] Executing task 'memory'
[my_server1] run: free -m
[my_server1] out: total used free shared buffers cached
[my_server1] out: Mem: 6964 1897 5067 0 166 222
[my_server1] out: -/+ buffers/cache: 1509 5455
[my_server1] out: Swap: 0 0 0
[my_server2] Executing task 'memory'
[my_server2] run: free -m
[my_server2] out: total used free shared buffers cached
[my_server2] out: Mem: 1666 902 764 0 180 572
[my_server2] out: -/+ buffers/cache: 148 1517
[my_server2] out: Swap: 895 1 894
我々は次のものと共に展開できます:
$ fab deploy
追加機能には、パラレル実行、リモートプログラムとの対話、およびホストグルーピングが含まれます。
Salt¶
Salt はオープンソースのインフラ管理ツールです。これは、中心点(マスターホスト)から複数のホスト(下位)へのリモートコマンド実行をサポートします。また、シンプルなテンプレートファイルを使用して複数のサーバーを構成するために使用できるシステム状態もサポートしています。
SaltはPythonバージョン2.6と2.7をサポートしており、pip経由でインストールできます:
$ pip install salt
マスターサーバーと任意の数のminionホストを設定したら、任意のシェルコマンドを実行するか、複雑なコマンドの既成モジュールをminionで使用できます。
次のコマンドは、pingモジュールを使用して利用可能なすべてのminionホストを一覧表示します。
$ salt '*' test.ping
ホストフィルタリングは、minion idを一致させるか、またはgrainシステムを使用して行います。 grains システムは、オペレーティングシステムのバージョンまたはCPUアーキテクチャのような静的ホスト情報を使用して、Saltモジュールのホスト分類を提供します。
次のコマンドは、grainsシステムを使用してCentOSを実行している利用可能なすべてのminionを一覧表示します。
$ salt -G 'os:CentOS' test.ping
Saltはまた、状態システムを提供する。 状態を使用してminionホストを構成することができます。
たとえば、minionホストが次の状態ファイルを読み込むように指示されると、Apacheサーバーがインストールされ、起動されます。
apache:
pkg:
- installed
service:
- running
- enable: True
- require:
- pkg: apache
状態ファイルは、YAML、Jinja2テンプレートシステムまたは純粋なPythonを使用して記述することができます。
Psutil¶
Psutil は、異なるシステム情報(例えば、CPU、メモリ、ディスク、ネットワーク、ユーザ、プロセス)へのインタフェースです。
ここでは、サーバーの過負荷を認識するための例を示します。 いずれかのテスト(ネット、CPU)が失敗すると、電子メールが送信されます。
# Functions to get system values:
from psutil import cpu_percent, net_io_counters
# Functions to take a break:
from time import sleep
# Package for email services:
import smtplib
import string
MAX_NET_USAGE = 400000
MAX_ATTACKS = 4
attack = 0
counter = 0
while attack <= MAX_ATTACKS:
sleep(4)
counter = counter + 1
# Check the cpu usage
if cpu_percent(interval = 1) > 70:
attack = attack + 1
# Check the net usage
neti1 = net_io_counters()[1]
neto1 = net_io_counters()[0]
sleep(1)
neti2 = net_io_counters()[1]
neto2 = net_io_counters()[0]
# Calculate the bytes per second
net = ((neti2+neto2) - (neti1+neto1))/2
if net > MAX_NET_USAGE:
attack = attack + 1
if counter > 25:
attack = 0
counter = 0
# Write a very important email if attack is higher than 4
TO = "you@your_email.com"
FROM = "webmaster@your_domain.com"
SUBJECT = "Your domain is out of system resources!"
text = "Go and fix your server!"
BODY = string.join(("From: %s" %FROM,"To: %s" %TO,"Subject: %s" %SUBJECT, "",text), "\r\n")
server = smtplib.SMTP('127.0.0.1')
server.sendmail(FROM, [TO], BODY)
server.quit()
psutilとクライアント/サーバ監視の能力をベースにした、広く拡張されたtopのようなフル端末アプリケーションは glance です。
Ansible¶
Ansible はオープンソースのシステム自動化ツールです。 Puppet や Chef に比べて最大の利点は、クライアントマシンにエージェントを必要としないことです。 PlayBook は Ansible の設定、デプロイメント、オーケストレーション言語であり、YAMLでJinja2でテンプレート化されています。
AnsibleはPythonバージョン2.6と2.7をサポートしており、pip経由でインストールできます:
$ pip install ansible
Ansibleには、アクセス権のあるホストを記述するインベントリファイルが必要です。 以下は、インベントリファイル内のすべてのホストに対してpingを実行するホストとプレイブックの例です。
次に、インベントリファイルの例を示します:
hosts.yml
[server_name]
127.0.0.1
ここでは、プレイブックの例です:
ping.yml
---
- hosts: all
tasks:
- name: ping
action: ping
プレイブックを実行するには:
$ ansible-playbook ping.yml -i hosts.yml --ask-pass
Ansibleのplaybookは hosts.yml
ファイル内のすべてのサーバにpingを実行します。また、Ansibleを使用してサーバーのグループを選択することもできます。 Ansibleの詳細については、 Ansible Docs を参照してください。
An Ansible tutorial も、Ansibleを使い始める上で非常に詳細な紹介です。
Chef¶
Chef は、サーバーやアプリケーションを物理的、仮想的、またはクラウドの場所に簡単に展開できるシステムとクラウドインフラストラクチャの自動化フレームワークです。 これが設定管理のための選択である場合、主にRubyを使用してインフラストラクチャコードを記述します。
Chefのクライアントは、インフラストラクチャの一部であるすべてのサーバー上で実行され、Chefサーバーと定期的にチェックして、システムが常に整列し、望ましい状態を表していることを確認します。 個々のサーバーにはそれぞれ独自のChefクライアントがあるため、各サーバーが構成され、この分散型アプローチによりシェフはスケーラブルな自動化プラットフォームになります。
Chefは、クックブックで実装されたカスタムレシピ(構成要素)を使用して動作します。基本的にインフラストラクチャーの選択肢のパッケージであるクックブックは、通常Chefサーバーに保存されます。 Digital Oceanチュートリアルシリーズ Chefの簡単なChefサーバーの作成方法を学びましょう。
シンプルなクックブックを作成するには、 knife コマンドを使用します:
knife cookbook create cookbook_name
Getting started with Chef は、Chefの初心者のための良い出発点であり、あなたのインフラストラクチャ構成のニーズを満たすために調整された良いリファレンスとして役立つことができる多くのコミュニティ管理された料理ブックは、Chef Supermarket で見つけることができます。
Puppet¶
Puppet は、システム管理者がITインフラストラクチャの状態を定義できるようにする、PuppetラボのIT自動化および構成管理ソフトウェアであり、物理マシンと仮想マシンを管理するエレガントな方法を提供します。
Puppetはオープンソースとエンタープライズの両方で利用可能です。 モジュールは、システムの状態を自動化または定義するために書かれた、小さな、共有可能なコード単位です。 Puppet Forge は、オープンソースとエンタープライズPuppetのためにコミュニティによって書かれたモジュールのリポジトリです。
Puppetエージェントは、状態を監視または変更する必要があるノードにインストールされます。 Puppetマスターと呼ばれる指定されたサーバーは、エージェントノードの編成を担当します。
エージェントノードは、オペレーティングシステム、カーネル、アーキテクチャ、IPアドレス、ホスト名などの基本的な事実をPuppet Masterに送信します。 Puppet Masterは、エージェントが提供する情報でカタログをコンパイルし、各ノードをどのように設定してエージェントに送信するかを決定します。 エージェントは、カタログに記載されている変更を適用し、レポートをPuppet Masterに送り返します。
Facterは、Puppetに同梱されている、システムに関する基本的な事実を引き出す興味深いツールです。 これらのファクトは、Puppetモジュールを記述する際に変数として参照できます。
$ facter kernel
Linux
$ facter operatingsystem
Ubuntu
Puppetにモジュールを書くことはかなり簡単です。 Puppetマニフェストが一緒にPuppetモジュールを形成します。 Puppetは .pp
の拡張子を持つマニフェストを明示します。 Puppetの ‘Hello World’ の例を次に示します。
notify { 'This message is getting logged into the agent node':
#As nothing is specified in the body the resource title
#the notification message by default.
}
システムベースのロジックを使用した別の例を次に示します。 オペレーティングシステムのファクトが、 $
が付いた変数としてどのように使われているかに注意してください。 同様に、 $hostname
で参照可能なホスト名のような他の事実にも当てはまります
notify{ 'Mac Warning':
message => $operatingsystem ? {
'Darwin' => 'This seems to be a Mac.',
default => 'I am a PC.',
},
}
Puppetにはいくつかのリソースタイプがありますが、パッケージファイルサービスのパラダイムは、構成管理の大部分を行うために必要なものです。 次のPuppetコードは、OpenSSH-Serverパッケージがシステムにインストールされていることを確認し、sshd設定ファイルが変更されるたびにsshdサービスが再起動するように通知します。
package { 'openssh-server':
ensure => installed,
}
file { '/etc/ssh/sshd_config':
source => 'puppet:///modules/sshd/sshd_config',
owner => 'root',
group => 'root',
mode => '640',
notify => Service['sshd'], # sshd will restart
# whenever you edit this
# file
require => Package['openssh-server'],
}
service { 'sshd':
ensure => running,
enable => true,
hasstatus => true,
hasrestart=> true,
}
詳細については、 Puppet Labsのドキュメント
Blueprint¶
課題
青写真について書く
継続的インテグレーション¶
どうして?¶
Kent Beckと一緒に 継続的インテグレーション (短略: CI)」を初めて書いたMartin Fowlerは、CIについて次のように説明しています。
継続的インテグレーションとは、チームのメンバーが頻繁に作業を統合するソフトウェア開発のことで、通常は1日に少なくとも1人は統合し、1日に複数のインテグレーションにつながります。 各インテグレーションは、自動化ビルド(テストを含む)によって検証され、統合エラーを可能な限り迅速に検出します。 多くのチームでは、このアプローチにより統合の問題が大幅に軽減され、チームが一貫性のあるソフトウェアをより迅速に開発できるようになりました。
Jenkins¶
Jenkins CI は、拡張可能な継続的インテグレーションエンジンです。 これを使います。
Tox¶
tox は、コンソールやCIサーバからPythonソフトウェアをパッケージ化、テスト、デプロイするオートメーションツールです。これは、以下の機能を提供する汎用の仮想管理およびテストコマンドラインツールです。
- 異なるPythonのバージョンとインタプリタでパッケージが正しくインストールされていることを確認する
- 各環境でのテストの実行、テストツールの選択
- 継続的インテグレーションサーバーのフロントエンドとして機能し、定型文を削減し、CIおよびシェルベースのテストをマージします。
Travis-CI¶
Travis-CI はオープンソースプロジェクトのテストを無料でビルドする分散型CIサーバです。 Pythonテストを実行する複数のワーカーを提供し、GitHubとシームレスに統合します。 この特定のチェンジセットがビルドを破るかどうかは、Pull Requestにコメントすることさえできます。 したがって、GitHubでコードをホストしている場合、travis-ciは継続的インテグレーションを使い始めることができます。
開始するには、この例のコンテンツで、 .travis.yml
ファイルをリポジトリに追加してください:
language: python
python:
- "2.6"
- "2.7"
- "3.2"
- "3.3"
# command to install dependencies
script: python tests/test_all_of_the_units.py
branches:
only:
- master
これにより、指定されたスクリプトを実行することによってリストされたすべてのPythonバージョンでプロジェクトがテストされ、マスターブランチのみがビルドされます。 通知や前後の手順など、さらに多くのオプションを有効にすることができます。 travis-ci docs はこれらすべてのオプションを説明しており、非常に徹底的です。
プロジェクトのテストを有効にするには、 travis-ci site に行き、あなたのGitHubアカウントでログインしてください。次に、あなたのプロファイル設定でプロジェクトをアクティブにし、あなたが移動する準備が整いました。 これから、あなたのプロジェクトのテストはすべてのGitHubへのプッシュで実行されます。
速度¶
最も一般的に使用されるPythonの実装であるCPythonは、CPUバインドされたタスクの速度が遅いです。 PyPy は高速です。
David Beazley のCPUバウンドテストコード(複数のテストで追加されたループ)を若干修正したものを使用すると、CPythonとPyPyの処理の違いを見ることができます。
# PyPy
$ ./pypy -V
Python 2.7.1 (7773f8fc4223, Nov 18 2011, 18:47:10)
[PyPy 1.7.0 with GCC 4.4.3]
$ ./pypy measure2.py
0.0683999061584
0.0483210086823
0.0388588905334
0.0440690517426
0.0695300102234
# CPython
$ ./python -V
Python 2.7.1
$ ./python measure2.py
1.06774401665
1.45412397385
1.51485204697
1.54693889618
1.60109114647
コンテキスト¶
The GIL¶
The GIL (Global Interpreter Lock) は、Pythonが複数のスレッドを同時に動作させる方法です。 Pythonのメモリ管理は完全にスレッドセーフではないため、複数のスレッドが同じPythonコードを同時に実行するのを防ぐためにGILが必要です。
David Beazley氏は、GILがどのように機能しているかについて素晴らしい ガイド を持っています。 彼はまた、Python 3.2で new GIL をカバーしています。 彼の結果は、Pythonアプリケーションのパフォーマンスを最大限にするには、GILの強み、アプリケーション固有のアプリケーションへの影響、コアの数、アプリケーションのボトルネックがどこにあるかを理解する必要があります。
C拡張機能¶
The GIL¶
あなたのスレッドをインタープリタに登録するためにC拡張を書くときには 特別な注意 が必要です。
C拡張機能¶
Cython¶
Cython は、Python用のCとC ++モジュールを書くことができるPython言語のスーパーセットを実装しています。 Cythonでは、コンパイルされたCライブラリから関数を呼び出すこともできます。 Cythonを使うと、Pythonの強力な変数や演算のタイプを利用できます。
Cythonでの厳密な型付けの例を次に示します:
def primes(int kmax):
"""Calculation of prime numbers with additional
Cython keywords"""
cdef int n, k, i
cdef int p[1000]
result = []
if kmax > 1000:
kmax = 1000
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] != 0:
i = i + 1
if i == k:
p[k] = n
k = k + 1
result.append(n)
n = n + 1
return result
素数を見つけるためのこのアルゴリズムの実装には、純粋なPythonで実装されている次のものと比較していくつかの追加のキーワードがあります。
def primes(kmax):
"""Calculation of prime numbers in standard Python syntax"""
p = range(1000)
result = []
if kmax > 1000:
kmax = 1000
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] != 0:
i = i + 1
if i == k:
p[k] = n
k = k + 1
result.append(n)
n = n + 1
return result
Cythonのバージョンでは、整数型と整数型の配列をC型にコンパイルしてPythonリストを作成することを宣言していることに注意してください。
def primes(int kmax):
"""Calculation of prime numbers with additional
Cython keywords"""
cdef int n, k, i
cdef int p[1000]
result = []
def primes(kmax):
"""Calculation of prime numbers in standard Python syntax"""
p = range(1000)
result = []
違いはなんですか? 上のCythonバージョンでは、標準Cと同様の方法で変数型と整数配列の宣言を見ることができます。たとえば、行3の cdef int n、k、i のようになります。この追加の型宣言(つまり整数) Cythonコンパイラは2番目のバージョンからより効率的なCコードを生成することができます。 標準のPythonコードは *.py
ファイルに保存されますが、Cythonコードは *.pyx
ファイルに保存されます。
スピードの違いは何ですか? 試してみよう!
import time
#activate pyx compiler
import pyximport
pyximport.install()
#primes implemented with Cython
import primesCy
#primes implemented with Python
import primes
print "Cython:"
t1= time.time()
print primesCy.primes(500)
t2= time.time()
print "Cython time: %s" %(t2-t1)
print ""
print "Python"
t1= time.time()
print primes.primes(500)
t2= time.time()
print "Python time: %s" %(t2-t1)
これらの行はいずれも発言が必要です:
import pyximport
pyximport.install()
pyximport モジュールは、 primes 関数のCythonでコンパイルされたバージョンで *.pyx
ファイル(例 primesCy.pyx
)をインポートすることを可能にします。 pyximport.install() コマンドはPythonインタプリタがCythonコンパイラを直接起動してCコードを生成できるようにします。これは自動的に *.so
Cライブラリにコンパイルされます。 Cythonでは、このライブラリをPythonコードで簡単に、効率的にインポートすることができます。 time.time() 関数を使うと、これら2つの異なる呼び出しの間の時間を比較して、500個の素数を見つけることができます。 標準のノートブック(デュアルコアAMD E-450 1.6 GHz)では、測定値は次のとおりです。
Cython time: 0.0054 seconds
Python time: 0.0566 seconds
そしてここに埋め込まれた ARM beaglebone マシンの出力があります:
Cython time: 0.0196 seconds
Python time: 0.3302 seconds
Pyrex¶
Shedskin?¶
並行性¶
Concurrent.futures¶
concurrent.futures モジュールは標準ライブラリのモジュールであり、 “非同期的に呼び出し可能なコールを実行するための高水準インターフェース” を提供します。これは、複数のスレッドやプロセスを並行処理に使用することに関するより複雑な詳細を抽象化し、ユーザが手近な作業を達成することに集中することを可能にします。
concurrent.futures モジュールは ThreadPoolExecutor と ProcessPoolExecutor の2つの主要なクラスを公開します。 ThreadPoolExecutorは、ユーザーがジョブを送信できるワーカースレッドのプールを作成します。これらのジョブは、次のワーカー・スレッドが使用可能になると、別のスレッドで実行されます。
ProcessPoolExecutorは同じ方法で動作しますが、ワーカーに複数のスレッドを使用するのではなく、複数のプロセスを使用します。 これによりGILのサイドステップが可能になりますが、ワーカープロセスに渡される方法のために、picklableオブジェクトのみが実行されて返されます。
GILの仕組みのおかげで、実行中のタスクには多くのブロッキング(ネットワーク経由での要求)があり、タスクが計算上高価な場合にはProcessPoolExecutorを使用するときにThreadPoolExecutorを使用するのが良い方法です。
2つのエグゼキュータを使用して並列実行するには、主に2つの方法があります。 1つの方法は map(func, iterables) メソッドです。 これは、すべてが並行して実行されることを除けば、組み込みの map() 関数とほぼ同じように機能します。 :
from concurrent.futures import ThreadPoolExecutor
import requests
def get_webpage(url):
page = requests.get(url)
return page
pool = ThreadPoolExecutor(max_workers=5)
my_urls = ['http://google.com/']*10 # Create a list of urls
for page in pool.map(get_webpage, my_urls):
# Do something with the result
print(page.text)
さらに、 submit(func, *args, **kwargs) メソッドは、実行可能な呼び出しをスケジュールし (func(*args, **kwargs))、 Future オブジェクトを返します。 呼び出し可能オブジェクトの実行を表します。
Futureオブジェクトは、スケジュールされた呼び出し可能ファイルの進行状況をチェックするために使用できるさまざまなメソッドを提供します。 これらには、
- cancel()
- コールをキャンセルしようとしています。
- cancelled()
- 呼び出しが正常にキャンセルされた場合はTrueを返します。
- running()
- 呼び出しが現在実行中でキャンセルできない場合はTrueを返します。
- done()
- 呼び出しが正常に取り消されたか、実行が終了した場合はTrueを返します。
- result()
- 呼び出しによって返された値を返します。 このコールは、スケジュールされたコールバックがデフォルトで戻るまでブロックされます。
- exception()
- 呼び出しによって発生した例外を返します。 例外が発生しなかった場合、これは None を返します。 これは result() のようにブロックされることに注意してください。
- add_done_callback(fn)
- スケジュールされたコールバックが返ってくるときに実行されるコールバック関数を ( fn(future) として)アタッチします。
from concurrent.futures import ProcessPoolExecutor, as_completed
def is_prime(n):
if n % 2 == 0:
return n, False
sqrt_n = int(n**0.5)
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return n, False
return n, True
PRIMES = [
112272535095293,
112582705942171,
112272535095293,
115280095190773,
115797848077099,
1099726899285419]
futures = []
with ProcessPoolExecutor(max_workers=4) as pool:
# Schedule the ProcessPoolExecutor to check if a number is prime
# and add the returned Future to our list of futures
for p in PRIMES:
fut = pool.submit(is_prime, p)
futures.append(fut)
# As the jobs are completed, print out the results
for number, result in as_completed(futures):
if result:
print("{} is prime".format(number))
else:
print("{} is not prime".format(number))
concurrent.futures モジュールには、Futuresを扱うための2つのヘルパー関数が含まれています。 as_completed(futures) 関数は、先物リストのイテレータを返し、完了したときの先物を返します。
提供された先物リストのすべての先物が完了するまで、 wait(futures) 機能は単にブロックされます。
concurrent.futures モジュールの使い方については、公式文書を参照してください。
スレッド¶
標準ライブラリには、ユーザが複数のスレッドを手動で扱うことを可能にする threading モジュールが付属しています。
別のスレッドで関数を実行するのは、呼び出し可能オブジェクトを Thread のコンストラクタに渡し、start() を呼び出すという単純な操作です。
from threading import Thread
import requests
def get_webpage(url):
page = requests.get(url)
return page
some_thread = Thread(get_webpage, 'http://google.com/')
some_thread.start()
スレッドが終了するまで待つには join() を呼び出します:
some_thread.join()
join() を呼び出した後は、スレッドがまだ生存しているかどうかを確認することをお勧めします(結合呼び出しがタイムアウトしたため):
if some_thread.is_alive():
print("join() must have timed out.")
else:
print("Our thread has terminated.")
複数のスレッドが同じメモリセクションにアクセスできるため、同時に複数のスレッドが同じリソースに書き込もうとする状況や、出力が特定のイベントのシーケンスやタイミングに依存する状況が発生することがあります。 これは、 data race または競合状態と呼ばれます。 これが発生すると、出力が文字化けしたり、デバッグが困難な問題が発生することがあります。 良い例がこの stackoverflow post です。
これを避ける方法は、各スレッドが共有リソースに書き込む前に取得する必要がある `Lock`_ を使用することです。 ロックは、コンテキストマネージャプロトコル (with 文)、または acquire() と release() を直接使用して取得して解放することができます。 ここに(やや工夫した)例があります:
from threading import Lock, Thread
file_lock = Lock()
def log(msg):
with file_lock:
open('website_changes.log', 'w') as f:
f.write(changes)
def monitor_website(some_website):
"""
Monitor a website and then if there are any changes,
log them to disk.
"""
while True:
changes = check_for_changes(some_website)
if changes:
log(changes)
websites = ['http://google.com/', ... ]
for website in websites:
t = Thread(monitor_website, website)
t.start()
ここでは、サイトリストの変更を確認するためのスレッドがたくさんあります。変更があった場合は、 log(changes) を呼び出すことによってその変更をファイルに書き込もうとします。 log() が呼び出されると、 with file_lock: でロックを取得するのを待ちます。 これにより、一度に1つのスレッドのみがファイルに書き込まれます。
プロセス生成¶
マルチプロセッシング¶
科学的アプリケーション¶
コンテキスト¶
Pythonは、高性能な科学アプリケーションに頻繁に使用されています。それは書くことが容易で、うまくいくので、学問や科学プロジェクトで広く使われています。
その高性能な性質から、Pythonでの科学計算は、一般的に高速言語(CやFORTRANなど)で書かれた外部ライブラリを利用することがよくあります。使用される主なライブラリは、 NumPy 、SciPy 、 Matplotlib です。これらのライブラリについて詳しくは、Pythonのガイドの範囲を超えています。しかし、科学的なPythonエコシステムの包括的な紹介は、 Python Scientific Lecture Notes
ツール¶
IPython¶
IPython は、科学者に大きな関心を寄せている機能を提供するPythonインタープリタの拡張バージョンです。 インラインモード は、グラフィックスとプロットを端末に表示することができます(Qtベースのバージョン)。さらに、 ノートブック モードは、ウェブベースのPythonノートブックを生成するリテラートプログラミングと再現可能な科学をサポートしています。このノートブックでは、結果と追加のコメント(HTML、LaTeX、Markdown)の横にPythonコードのチャンクを保存することができます。ノートブックは、さまざまなファイル形式で共有してエクスポートすることができます。
ライブラリ¶
NumPy¶
NumPy は、高レベルの数学的関数のためにC(およびFORTRAN)で書かれた低レベルのライブラリです。 NumPyは、多次元配列や配列を操作する関数を使用して、Python上でより遅いアルゴリズムを実行する問題を巧みに克服します。 どのアルゴリズムも配列の関数として表現でき、アルゴリズムを素早く実行できます。
NumPyはSciPyプロジェクトの一部であり、基本的な要件だけを必要とする人はSciPyの残りの部分をインストールせずに使用できるように、別のライブラリとしてリリースされています。
NumPyは、Python 2.4から2.7.2および3.1以降のバージョンと互換性があります。
Numba¶
Numba はNumPy対応Pythonコンパイラ(Just-In-Time(JIT)専門コンパイラ)で、注釈付きPython(およびNumPy)コードをLLVM(Low Level Virtual Machine) 特別なデコレータを通して。 簡潔に言えば、Numbaは、実行時にネイティブに実行できるコードにLLVMを使用してPythonコードをコンパイルするシステムを使用します。
SciPy¶
SciPy はNumPyをより多くの数学的関数に使用するライブラリです。 SciPyはNumPy配列を基本的なデータ構造として使用し、線形代数、積分(微積分)、常微分方程式の解法、信号処理など、科学プログラミングのさまざまな一般的なタスクのモジュールを備えています。
Matplotlib¶
Matplotlib は、インタラクティブな2Dと3Dプロットを作成するための柔軟なプロットライブラリであり、原稿の質の高い数字として保存することもできます。 APIは多くの点で、 MATLAB を反映しており、MATLABユーザーのPythonへの移行を容易にしています。多くの例とそれらを再作成するソースコードは、 matplotlib gallery で利用できます。
Pandas¶
Pandas は、Numpyをベースにしたデータ操作ライブラリであり、データのアクセス、索引付け、マージ、およびグループ化を容易にするための多くの便利な機能を提供します。 主なデータ構造(DataFrame)は、R統計パッケージにあるものに近いです。 つまり、名前の索引付け、時系列操作、およびデータの自動整列を使用する異種データ表です。
リソース¶
科学的なPythonパッケージのインストールは、これらのパッケージの多くがコンパイルする必要があるPython C拡張として実装されるので、面倒なことがあります。この節では、サイエンスPythonパッケージのプリコンパイル済みでインストールが簡単なコレクションを提供する、さまざまないわゆる科学Pythonディストリビューションを紹介します。
Python拡張パッケージ用の非公式Windowsバイナリ¶
科学的コンピューティングを行う多くの人々がWindows上にありますが、科学的コンピューティングパッケージの多くは、このプラットフォームで構築してインストールすることは難しいことで有名です。 Christoph Gohlke しかし、多くの便利なPythonパッケージのWindowsバイナリのリストをコンパイルしました。パッケージのリストは、主に科学的なPythonリソースからより一般的なリストに成長しました。 Windowsの場合は、チェックアウトすることができます。
Anaconda¶
Continuum Analytics は Anaconda Python Distribution を提供しています。これには一般的な科学Pythonパッケージと多くの パッケージは、データ分析と大きなデータに関連しています。 Anaconda自体は無料で、Continuumは独自のアドオンを多数販売しています。 アドオンの無料ライセンスは、学者や研究者が利用できます。
画像操作¶
ほとんどの画像処理および操作技術は、Python Imaging Library(PIL)とOpenSource Computer Vision(OpenCV)の2つのライブラリを使用して効果的に実行できます。
両方の簡単な説明を以下に示します。
Python Imaging Library¶
Python Imaging Library またはPILは、Pythonでの画像操作のためのコアライブラリの1つです。 残念ながら、2009年の最後のリリースでは、その開発は停滞しています。
幸いなことに、積極的に開発されたPILのフォーク Pillow があります。インストールが簡単で、すべてのオペレーティングシステムで動作し、Python 3をサポートしています。
インストール¶
Pillowをインストールする前に、Pillowの前提条件をインストールする必要があります。 Pillowのインストール手順 でお使いのプラットフォームの手順を見つけてください。
その後、それは簡単です:
$ pip install Pillow
例¶
from PIL import Image, ImageFilter
#Read image
im = Image.open( 'image.jpg' )
#Display image
im.show()
#Applying a filter to the image
im_sharp = im.filter( ImageFilter.SHARPEN )
#Saving the filtered image to a new file
im_sharp.save( 'image_sharpened.jpg', 'JPEG' )
#Splitting the image into its respective bands, i.e. Red, Green,
#and Blue for RGB
r,g,b = im_sharp.split()
#Viewing EXIF data embedded in image
exif_data = im._getexif()
exif_data
Pillowライブラリの例は、 Pillow tutorial にあります。
OpenSource Computer Vision¶
OpenSource Computer Visionは、一般にOpenCVとして知られ、PILよりも高度な画像操作と処理ソフトウェアです。 いくつかの言語で実装されており、広く使用されています。
インストール¶
Pythonでは、OpenCVを使った画像処理は cv2
と NumPy
モジュールを使って実装されています。 OpenCVのインストール手順 はあなた自身でプロジェクトを設定する際の手引きです 。
NumPyは、Python Package Index(PyPI)からダウンロードできます。
$ pip install numpy
Example¶
from cv2 import *
import numpy as np
#Read Image
img = cv2.imread('testimg.jpg')
#Display Image
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#Applying Grayscale filter to image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Saving filtered image to new file
cv2.imwrite('graytest.jpg',gray)
この チュートリアルのコレクション には、Pythonで実装されたOpenCVの例がたくさんあります
データシリアライズ¶
データシリアライズとは何ですか?¶
データシリアライズは、構造化されたデータを、元の構造が復元されるように共有または格納できる形式に変換する概念です。場合によっては、データシリアライズの第2の目的は、シリアライズされたデータのサイズを最小限に抑え、ディスクのスペースまたは帯域幅の要件を最小限に抑えることです。
Pickle¶
Pythonのネイティブデータシリアライゼーションモジュールは、 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 )
#Use loads to de-serialize an object
received_grades = pickle.loads( serial_grades )
XML解析¶
untangle¶
untangle は、XML文書を受け取り、構造内のノードと属性を反映するPythonオブジェクトを返す単純なライブラリです。
たとえば、次のようなXMLファイルがあります:
<?xml version="1.0"?>
<root>
<child name="child1">
</root>
次のようにロードすることができます:
import untangle
obj = untangle.parse('path/to/file.xml')
そして次のように子要素の名前を取得できます:
obj.root.child['name']
untangleは、文字列またはURLからXMLを読み込むこともサポートしています。
xmltodict¶
xmltodict は、XMLをJSONのように扱えるようにするためのもう一つの単純なライブラリです。
次のようなXMLファイル:
<mydocument has="an attribute">
<and>
<many>elements</many>
<many>more elements</many>
</and>
<plus a="complex">
element as well
</plus>
</mydocument>
次のようにPython辞書にロードすることができます:
import xmltodict
with open('path/to/file.xml') as fd:
doc = xmltodict.parse(fd.read())
次に、次のように要素、属性、および値にアクセスできます:
doc['mydocument']['@has'] # == u'an attribute'
doc['mydocument']['and']['many'] # == [u'elements', u'more elements']
doc['mydocument']['plus']['@a'] # == u'complex'
doc['mydocument']['plus']['#text'] # == u'element as well'
xmltodictは、未解析関数を使用してXMLへのラウンドトリップを可能にし、メモリに収まらないファイルを処理するのに適したストリーミングモードを持ち、名前空間をサポートします。
JSON¶
json ライブラリは文字列やファイルからJSONを解析できます。 ライブラリは、JSONをPythonの辞書またはリストに解析します。 また、Pythonの辞書やリストをJSON文字列に変換することもできます。
JSONの解析¶
JSONデータを含む次の文字列を取得します。
json_string = '{"first_name": "Guido", "last_name":"Rossum"}'
これは次のように解析できます:
import json
parsed_json = json.loads(json_string)
今すぐ通常の辞書として使用することができます:
print(parsed_json['first_name'])
"Guido"
次のものをJSONに変換することもできます:
d = {
'first_name': 'Guido',
'second_name': 'Rossum',
'titles': ['BDFL', 'Developer'],
}
print(json.dumps(d))
'{"first_name": "Guido", "last_name": "Rossum", "titles": ["BDFL", "Developer"]}'
simplejson¶
JSONライブラリはPython 2.6に追加されました。 以前のバージョンのPythonを使用している場合、 simplejson ライブラリはPyPI経由で利用できます。
simplejsonはjson標準ライブラリを模倣しています。 古いバージョンのPythonを使用する開発者がjsonのlibで利用可能な最新の機能を使用できるように、これを利用できます。
simplejsonを別の名前でインポートして、jsonライブラリが利用できないときにsimplejsonを使用することができます:
import simplejson as json
simplejsonをjsonとしてインポートした後、上記の例はすべて、標準のjsonライブラリを使用しているかのように動作します。
暗号¶
暗号¶
Cryptography は、暗号レシピとプリミティブを提供する、積極的に開発されたライブラリです。 Python 2.6-2.7、Python 3.3+、PyPyをサポートしています。
暗号は、レシピと危険物(ハザード)の2つの層に分かれています。 レシピ層は適切な共通鍵暗号化のための簡単なAPIを提供し、ハザード層は低レベルの暗号プリミティブを提供します。
インストール¶
$ pip install cryptography
例¶
高レベルの共通鍵暗号レシピを使用したコード例:
from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher_suite = Fernet(key)
cipher_text = cipher_suite.encrypt(b"A really secret message. Not for prying eyes.")
plain_text = cipher_suite.decrypt(cipher_text)
PyCrypto¶
PyCrypto は安全なハッシュ関数とさまざまな暗号化アルゴリズムを提供する別のライブラリです。 Python 2.1から3.3までのバージョンをサポートしています。
インストール¶
$ pip install pycrypto
例¶
from Crypto.Cipher import AES
# Encryption
encryption_suite = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
cipher_text = encryption_suite.encrypt("A really secret message. Not for prying eyes.")
# Decryption
decryption_suite = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
plain_text = decryption_suite.decrypt(cipher_text)
機械学習¶
Pythonには、データ分析、統計、機械学習のための膨大な数のライブラリがあり、多くのデータ科学者にとって選択肢の多い言語になっています。
マシンラーニングやその他のデータサイエンスアプリケーションで広く使われているパッケージのいくつかを以下に挙げます。
Scipyスタック¶
Scipyスタックは、統計解析とデータの可視化のために、データサイエンスで使用される一連のコアヘルパーパッケージで構成されています。膨大な数の機能と使い易さのために、このスタックは、ほとんどのデータサイエンスアプリケーションに欠かせないものと考えられています。
Stackは以下のパッケージで構成されています(ドキュメントへのリンク):
このスタックにはPythonも付属していますが、上記のリストから除外されています。
scikit-learn¶
ScikitはPythonのためのフリーでオープンソースの機械学習ライブラリです。線形回帰、分類器、SVM、k-means、ニューラルネットワークなどの多くのアルゴリズムを実装するための既製の関数を提供します。トレーニングやテストに直接使用できるサンプルデータセットもいくつかあります。
そのスピード、堅牢性、使いやすさのため、多くの機械学習アプリケーションで最も広く使用されているライブラリの1つです。
インストール¶
PyPIを通じて:
pip install -U scikit-learn
condaを通して:
conda install scikit-learn
scikit-learnにはAnaconda(上記参照)が同梱されています。 詳しいインストール方法については、 このリンク を参照してください。
例¶
この例では、簡単な分類子を Iris dataset でトレーニングします。これはscikit-learnでバンドルされています。
このデータセットは、葉の長さ、葉の幅、花弁の長さ、花弁の幅の4つの特徴を取り、それらを3つの花種(ラベル):セソサ、バーシカラー、またはバージニアに分類します。 ラベルはデータセット内の数字として表されています:0(setosa)、1(versicolor)、2(virginica)。
アイリスデータセットをシャッフルし、別々のトレーニングとテストセットに分けます:テストのための最後の10データポイントを保持し、トレーニングのために休みます。 次に、トレーニングセットの分類子を訓練し、テストセットを予測します。
from sklearn.datasets import load_iris
from sklearn import tree
from sklearn.metrics import accuracy_score
import numpy as np
#loading the iris dataset
iris = load_iris()
x = iris.data #array of the data
y = iris.target #array of labels (i.e answers) of each data entry
#getting label names i.e the three flower species
y_names = iris.target_names
#taking random indices to split the dataset into train and test
test_ids = np.random.permutation(len(x))
#splitting data and labels into train and test
#keeping last 10 entries for testing, rest for training
x_train = x[test_ids[:-10]]
x_test = x[test_ids[-10:]]
y_train = y[test_ids[:-10]]
y_test = y[test_ids[-10:]]
#classifying using decision tree
clf = tree.DecisionTreeClassifier()
#training (fitting) the classifier with the training set
clf.fit(x_train, y_train)
#predictions on the test dataset
pred = clf.predict(x_test)
print pred #predicted labels i.e flower species
print y_test #actual labels
print (accuracy_score(pred, y_test))*100 #prediction accuracy
私たちはランダムに分割しているので、分類器は繰り返しごとに列車を辿るため、精度は異なる場合があります。 上記のコードを実行すると、次のようになります。
[0 1 1 1 0 2 0 2 2 2]
[0 1 1 1 0 2 0 2 2 2]
100.0
最初の行には、分類器によって予測されたテストデータのラベル(すなわち、花種)が含まれ、2行目には、データセットに示された実際の花種が含まれています。 このため、今回は100%の精度が得られます。
scikit-learnの詳細は documentation をご覧ください。
C/C ++ライブラリとのインタフェース¶
C外部関数インタフェース¶
CFFI は、CPythonとPyPyの両方からCとインタフェースするための使いやすいメカニズムを提供します。実行可能モジュール(LoadLibraryまたはdlopenと同じ機能を本質的に公開します)から関数を動的にロードおよび実行できるインラインABI互換モード(下記の例)とAPIモードをサポートしています。 C拡張モジュール。
ABIインタラクション¶
1 2 3 4 5 6 7 | from cffi import FFI
ffi = FFI()
ffi.cdef("size_t strlen(const char*);")
clib = ffi.dlopen(None)
length = clib.strlen("String to be evaluated.")
# prints: 23
print("{}".format(length))
|
ctypes¶
ctypes はCPythonのC / C ++とのインタフェースのための事実上のライブラリであり、CのネイティブCインタフェースへのフルアクセスだけでなく、 (例えば、Windowsの場合はkernel32、*nixの場合はlibc)、実行時にDLLや共有オブジェクトなどの動的ライブラリを読み込み、インタフェースするためのサポートも提供します。 システムAPIとやりとりするためのさまざまな型の型を持ち合わせており、構造体や共用体などの複雑な型を簡単に定義でき、必要に応じてパディングやアラインメントなどの変更が可能です。 使用するのはちょっと難しいかもしれませんが、 struct モジュールと関連して、基本的にあなたのデータ型 純粋なC(++)メソッドで使用可能なものに変換されます。
構造体の構造¶
MyStruct.h
1 2 3 4 | struct my_struct {
int a;
int b;
};
|
MyStruct.py
1 2 3 4 | import ctypes
class my_struct(ctypes.Structure):
_fields_ = [("a", c_int),
("b", c_int)]
|
SWIG¶
SWIG は、厳密にはPythonに焦点を当てていませんが(スクリプト言語の数が多い)、C/C++ ヘッダーファイルから解釈言語用のバインディングを生成するためのツールです。 消費者はインターフェイスファイル(チュートリアルとドキュメントで詳述)を定義し、必要なC / C ++ヘッダーを組み込み、それらに対してビルドツールを実行するだけで簡単に使用できます。 それにはいくつかの制限がありますが(現在、新しいC ++機能の小さなサブセットに問題があるようで、テンプレートの重いコードを少し冗長にすると少し冗長になります)、多くの機能を提供し、多くの機能を公開します 少しの努力でPythonに さらに、SWIGが(インターフェイスファイル内で)作成したバインディングを演算子や組み込みメソッドのオーバーロードに容易に拡張でき、効果的にC ++例外を再キャストしてPythonなどがキャッチ可能にすることができます。
例: __repr__ のオーバーロード¶
MyClass.h
1 2 3 4 5 6 7 | #include <string>
class MyClass {
private:
std::string name;
public:
std::string getName();
};
|
myclass.i
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | %include "string.i"
%module myclass
%{
#include <string>
#include "MyClass.h"
%}
%extend MyClass {
std::string __repr__()
{
return $self->getName();
}
}
%include "MyClass.h"
|
Boost.Python¶
Boost.Python では、C++オブジェクトの機能を公開するために少し手作業が必要ですが、すべての 同じ機能をSWIGが実行し、C++でPyObjectにアクセスするためのラッパーを提供したり、SWIGラッパーオブジェクトを抽出したり、PythonのビットをC++コードに埋め込んだりすることもできます。
大規模な Python コードへの出荷¶
本書のこのパートは、Python コードのデプロイに焦点を当てています。
コードのパッケージ化¶
コードをパッケージ化して、他の開発者と共有します。例えば、他の開発者が自分のアプリケーションで使うためのライブラリや、 ‘py.test’ のような開発ツールを共有するためです。
PyPIやpipなどのツールによる配布方法の利点は、他の開発者達にあなたのパッケージのインストールとダウンロード、カジュアルな実験、大規模で専門的なシステムの一部としての使用を簡単に行え、エコシステムとして確立されています。
この方法でPythonコードを共有するのは、定評のある規約です。コードがPyPIにパッケージ化されていない場合、他の開発者がコードを見つけて既存のプロセスの一部として使用することは難しくなります。彼らは、このようなプロジェクトについては、管理や放棄の疑いが強いとみなします。
このようにコードを配布することの欠点は、必要なバージョンのPythonをインストールする方法と、pyなどのツールを使用してコードの他の依存関係をインストールすることができることを受信者が理解していることです。 これは他の開発者に配布する場合は問題ありませんが、この方法はアプリケーションをエンドユーザーに配布する場合には不適切です。
Pythonパッケージングガイド には、Pythonパッケージの作成と保守に関する広範なガイドがあります。
パッケージングの代替案¶
アプリケーションをエンドユーザに配布するには、以下を行う必要があります。 freeze your application
Linuxでは、Linuxディストリビューションパッケージ の作成 (例:DebianやUbuntu用の.debファイル) を参考にしてください。
Pythonデベロッパー向け¶
オープンソースのPythonモジュールを書いているなら、PyPI と呼ばれ、よりよく知られている The Cheeseshop は、それをホストする場所です。
パーソナルPyPI¶
PyPI以外のソースからパッケージをインストールする場合(例えば、パッケージが proprietary の場合)、インストールが必要なパッケージを保持するディレクトリから実行される単純なhttpサーバをホストすることによって実行できます。
例を示すことは常に有益です
たとえば、 MyPackage.tar.gz
という名前のパッケージをインストールし、それがあなたのディレクトリ構造であると仮定すると:
- archive
- MyPackage
- MyPackage.tar.gz
コマンドプロンプトで次のように入力します:
$ cd archive
$ python -m SimpleHTTPServer 9000
これは、ポート9000で実行される単純なhttpサーバーを実行し、MyPackage などのすべてのパッケージをリストします。 これで、Pythonパッケージインストーラを使用して MyPackage をインストールできます。 Pipを使用すると、次のようになります。
$ pip install --extra-index-url=http://127.0.0.1:9000/ MyPackage
パッケージ名と同じ名前のフォルダを持つことは、ここでは 非常に重要です。 私は一度それに騙された。 しかし、MyPackage
という名前のフォルダを作成し、MyPackage.tar.gz
を 冗長 にしておくと、MyPackageをインストールすることができます:
$ pip install http://127.0.0.1:9000/MyPackage.tar.gz
pypiserver¶
Pypiserver はPyPI互換の最小限のサーバです。 これは、easy_installまたはpipにパッケージのセットを提供するために使用することができます。 管理コマンド(-U
)のような便利な機能が含まれており、すべてのパッケージをPyPI上の最新バージョンに更新します。
S3-Hosted PyPi¶
パーソナルPyPiサーバのための簡単なオプションの1つは、Amazon S3を使用することです。これの前提条件は、S3バケットを備えたAmazon AWSアカウントを持っていることです。
- PyPiまたは別のソースからすべての要件をインストールする
- pip2piをインストールする
pip install git+https://github.com/wolever/pip2pi.git
- pip2tgzおよびdir2piコマンドの場合はpip2pi READMEに従ってください。
pip2tgz packages/ YourPackage
(orpip2tgz packages/ -r requirements.txt
)dir2pi packages/
- 新しいファイルをアップロードする
- Cyberduckのようなクライアントを使って
packages
フォルダ全体をs3バケットに同期させます - あなたは必ず
packages/simple/index.html
と全ての新しいファイルとディレクトリをアップロードしてください
- 新しいファイルのアクセス許可を修正する
- デフォルトでは、S3バケットに新しいファイルをアップロードすると、不正なアクセス権が設定されます。
- Amazon Webコンソールを使用して、ファイルのREAD権限をEVERYONEに設定します。
- パッケージをインストールしようとしたときにHTTP 403が表示された場合は、アクセス権を正しく設定してください。
- すべて完了
- あなたは今あなたのパッケージをインストールすることができます
pip install --index-url=http://your-s3-bucket/packages/simple / YourPackage
Linuxディストリビューションの場合¶
Linuxディストリパッケージを作成することは、間違いなくLinux上でコードを配布する「正しい方法」です。
ディストリビューションパッケージにはPythonインタプリタが含まれていないので、ダウンロード約2MBをインストールします freezing your application
また、ディストリビューションがPython用の新しいセキュリティアップデートをリリースすると、その新しいバージョンのPythonを使ってアプリケーションが自動的に起動します。
bdist_rpmコマンドは、Red HatやSuSEのようなディストリビューションで使用する RPMファイルを生成すること は簡単です。
しかし、各ディストリビューションのフォーマット(Debian / Ubuntuの場合は.deb、RedHat/Fedoraの場合は.rpmなど)に必要なさまざまな設定を作成し、維持することは相当量の作業です。コードが他のプラットフォームで配布する予定のアプリケーションである場合は、WindowsとOSX用にアプリケーションをフリーズするために必要な別の設定を作成して維持する必要があります。クロスプラットフォーム フリーズツール のいずれかのために、Linuxのすべてのディストリビューションのためのスタンドアロンの実行可能ファイルを生成する単一の設定を作成して維持するだけでは、 WindowsとOSXだけでなく、
配布パッケージを作成することは、あなたのコードが現在配布物でサポートされていないバージョンのPython用である場合にも問題になります。 Ubuntuエンドユーザの いくつかのバージョン に ‘dead-snakes’ PPA sudo apt-repository を追加する必要があることを伝える必要があります コマンドを使用して.debファイルをインストールする前に、非常に敵対的なユーザーエクスペリエンスを作ります。 それだけでなく、すべてのディストリビューションでこれらの手順に相当するカスタムを維持しなければならず、さらに悪いことに、ユーザーに読んで理解させ、行動させる必要があります。
すべてのことを言って、ここでそれを行う方法です:
便利なツール¶
- fpm
- alien
- dh-virtualenv (APT/DEBオムニバスパッケージング用)
コードのフリーズ¶
コードを “フリーズ” すると、アプリケーションコードとPythonインタプリタのすべてを含む、エンドユーザーに配布するための単一ファイルの実行可能ファイルが作成されます。
「Dropbox」、「Eve Online」、「Civilization IV」、BitTorrentクライアントなどのアプリケーションがこれを行います。
この方法を配布することの利点は、必要なバージョンのPython(またはいずれか)がインストールされていなくても、アプリケーションが「うまくいく」ことです。 Windowsでは、そして多くのLinuxディストリビューションやOS Xでも、適切なバージョンのPythonはまだインストールされていません。
さらに、エンドユーザソフトウェアは常に実行形式でなければなりません。 .py
で終わるファイルは、ソフトウェアエンジニアやシステム管理者のためのものです。
フリーズの欠点の1つは、配布量を約2〜12MB増やすことです。 また、Pythonのセキュリティ上の脆弱性が修正されたときに、アプリケーションの更新版を出荷する責任があります。
フリーズの代替¶
あなたのコードをパッケージ化する は、ライブラリやツールを他の開発者に配布するためのものです。
Linuxの場合、フリーズする代わりに、 Linuxディストリビューションパッケージを作成するためのパッケージング (DebianやUbuntuでは.debファイル、Red HatやSuSEでは.rpmファイル) )
課題
“コードをフリーズする” スタブを記入
フリーズツールの比較¶
ソリューションとプラットフォーム/サポートされる機能:
Solution | Windows | Linux | OS X | Python 3 | License | One-file mode | Zipfile import | Eggs | pkg_resources support |
---|---|---|---|---|---|---|---|---|---|
bbFreeze | yes | yes | yes | no | MIT | no | yes | yes | yes |
py2exe | yes | no | no | yes | MIT | yes | yes | no | no |
pyInstaller | yes | yes | yes | yes | GPL | yes | no | yes | no |
cx_Freeze | yes | yes | yes | yes | PSF | no | yes | yes | no |
py2app | no | no | yes | yes | MIT | no | yes | yes | yes |
注釈
Linux上のPythonコードをWindows実行可能ファイルにフリーズすることはPyInstaller で一度しかサポートされず、後で廃止されました 。
注釈
すべてのソリューションは、py2appを除くターゲットマシンにMS Visual C++ dllをインストールする必要があります。 Pyinstallerだけが --onefile
を渡すときにdllをバンドルする自己実行可能なexeを作成します Configure.py
。
Windows¶
py2exe¶
前提条件は Python on Windows をインストールすることです。
- http://sourceforge.net/projects/py2exe/files/py2exe/ をダウンロードしてインストールします。
- 書き込み
setup.py
(設定オプションのリスト):
from distutils.core import setup
import py2exe
setup(
windows=[{'script': 'foobar.py'}],
)
- (オプション) インクルードアイコン
- (オプション) 1ファイルモード
- 生成する
.exe
intodist
ディレクトリ:
$ python setup.py py2exe
- Microsoft Visual CランタイムDLLを提供します。 2つのオプションがあります: ターゲットマシンにDLLをグローバルにインストールする または dllを .exe と一緒に配布する 。
OS X¶
py2app¶
PyInstaller¶
PyInstallerを使用して、Mac OS X 10.6(Snow Leopard)以降のUnix実行ファイルやウィンドウアプリケーションをビルドすることができます。
PyInstallerをインストールするには、pipを使用します:
$ pip install pyinstaller
標準のUnix実行ファイルを作成するには、次のようにします script.py
:
$ pyinstaller script.py
これは、
script.spec
ファイルmake
ファイルに似ていますbuild
フォルダ。いくつかのログファイルを保持します。dist
フォルダです。メインの実行ファイルscript
といくつかの依存するPythonライブラリを保持しています。
script.py
としてすべて同じフォルダ内にあります。 PyInstallerは script.py
で使われているすべてのPythonライブラリを dist
フォルダに置きます。したがって、実行ファイルを配布するときには dist
フォルダ全体を配布してください。
script.spec
ファイルは ビルドをカスタマイズ するために編集することができます。
- データファイルを実行可能ファイルにバンドルする
- PyInstallerが自動的に推論できない実行時ライブラリ (
.dll
または.so
ファイル) を含みます - Python実行時オプションを実行可能ファイルに追加する
今すぐ script.spec
は pyinstaller
で実行することができます (script.py
を再度使用するのではなく):
$ pyinstaller script.spec
スタンドアロンのウィンドウズOS Xアプリケーションを作成するには、--windowed
オプションを使います
$ pyinstaller --windowed script.spec
これは dist
フォルダに script.app
を作成します。 PyQt や PySide のようなPythonコードでGUIパッケージを使うようにしてください。アプリのグラフィック部分を制御する。
いくつかのオプションがあります script.spec
はMac OS Xアプリケーションバンドルに関連しています ここ 。 たとえば、アプリケーションのアイコンを指定するには、 icon=\ path\to\icon.icns
オプションを使用します。
Python 開発環境¶
本書のこのパートは、Python 開発環境と、Python コードの作成に使用できるベストプラクティスなツールに焦点を当てています。
あなたの開発環境¶
テキストエディタ¶
プレーンテキストを編集できるものは、Pythonコードを書くためにはうまくいくでしょう。 しかし、より強力なエディタを使用すると、あなたの人生は少し楽になるかもしれません。
Vim¶
Vimは、メニューやアイコンの代わりにキーボードショートカットを使用するテキストエディタです。
Vimエディタには、Python開発を支援するためのいくつかのプラグインと設定があります。
Pythonでのみ開発する場合は、インデントと改行のデフォルト設定を PEP 8 に準拠した値に設定するのがよいでしょう。あなたのホームディレクトリで、 .vimrc
というファイルを開き、
次の行:
set textwidth=79 " lines longer than 79 columns will be broken
set shiftwidth=4 " operation >> indents 4 columns; << unindents 4 columns
set tabstop=4 " a hard TAB displays as 4 columns
set expandtab " insert spaces when hitting TABs
set softtabstop=4 " insert/delete 4 spaces when hitting a TAB/BACKSPACE
set shiftround " round indent to multiple of 'shiftwidth'
set autoindent " align the new line indent with the previous line
これらの設定では、改行は79文字の後に挿入され、インデントはタブごとに4スペースに設定されます。 Vimを他の言語にも使用している場合は、indent という便利なプラグインがあります。 これはPythonソースファイルのインデント設定を処理します。
syntax という便利な構文プラグインもあります。 これは、Vim 6.1に含まれている構文ファイルの改良点です。
これらのプラグインは、Pythonで開発するための基本的な環境を提供します。
Vimを最大限に活用するには、コードの構文エラーとPEP8準拠を継続的に確認する必要があります。
幸いにも PEP8 と Pyflakes があなたのためにこれを行います。
あなたのVimが +python
でコンパイルされている場合は、非常に便利なプラグインを利用してエディタ内からこれらのチェックを行うこともできます。
PEP8チェックとpyflakesの場合、vim-flake8 をインストールすることができます。
これでVimに必要なホットキーやアクションに Flake8
関数をマップすることができます。
プラグインは画面の下部にエラーを表示し、対応する行にジャンプする簡単な方法を提供します。
ファイルを保存するたびにこの関数を呼び出すのは非常に便利です。
これを行うには、次の行をファイルに追加します
.vimrc
:
autocmd BufWritePost *.py call Flake8()
syntastic を既に使用している場合は、書き込み時にPyflakesを実行し、クイックフィックスウィンドウでエラーと警告を表示するように設定できます。 ステータスバーにステータスと警告メッセージを表示する設定例は、次のとおりです:
set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*
let g:syntastic_auto_loc_list=1
let g:syntastic_loc_list_height=5
Pythonモード¶
Python-mode は、VimでPythonコードを操作するための複雑なソリューションです。 それは:
- 任意の組み合わせの非同期Pythonコード検査 (
pylint
、pyflakes
、pep8
、mccabe
) - Rope によるコードリファクタリングとオートコンプリート
- 高速Python折りたたみ
- Virtualenvのサポート
- Pythonのドキュメントを検索し、Pythonコードを実行する
- 自動PEP8_ のエラー修正
そしてさらに。
Emacs¶
Emacsはもう一つの強力なテキストエディタです。 それは完全にプログラム可能(lisp)ですが、それは正しくワイヤリングするいくつかの仕事かもしれません。 既にEmacsのユーザであれば、EmacsWikiの Python Programming in Emacs が良いスタートです。
- Emacs自体にはPythonモードがあります。
TextMate¶
TextMate は、オペレーティングシステムに対するAppleのアプローチをテキストエディタの世界にもたらします。 UNIXの基盤とGUIを橋渡しすることにより、TextMateは熟練したスクリプタや初心者ユーザの利益のために、両方の世界のベストをチェリーピックアップします。
Sublime Text¶
Sublime Text は、コード、マークアップ、散文の洗練されたテキストエディタです。 すっきりとしたユーザーインターフェイス、優れた機能、素晴らしいパフォーマンスが大好きです。
Sublime Textは、Pythonコードの編集をサポートしており、PythonをプラグインAPIとして使用しています。 また、様々な種類のプラグインがあります。その中には 、エディタ内のPEP8チェックとコード “linting” があります。
Atom¶
Atom は、atom-shell上に基づく21世紀のハック可能なテキストエディタであり、私たちがお気に入りのエディタについて愛するすべてのものに基づいています。
AtomはWebネイティブ(HTML、CSS、JS)で、モジュール設計と簡単なプラグイン開発に重点を置いています。 ネイティブのパッケージ制御と多数のパッケージが付属しています。 Pythonの開発には、Linter と linter-flake8 の組み合わせを推奨します。
IDEs¶
PyCharm / IntelliJ IDEA¶
PyCharm はJetBrainsによって開発されたもので、IntelliJ IDEAでも知られています。 Python Plug-In を使用して、Pythonプラグインと同じコードベースを共有し、PyCharmの機能のほとんどをIntelliJにもたらすことができます。 PyCharmには、プロフェッショナル版(30日間無料体験版)とコミュニティ版(Apache 2.0ライセンス)の2つのバージョンがあります。
Python (on Visual Studio Code)¶
Python for Visual Studio は、 Visual Studio Code IDE の拡張です。 これはMac、Windows、Linuxをサポートする、無料の軽量オープンソースIDEです。 Node.jsやPythonなどのオープンソース技術を使用して構築され、Intellisense(オートコンプリート)、ローカルとリモートのデバッグ、lintingなどの魅力的な機能を備えています。
MIT licensed.
Enthought Canopy¶
Enthought Canopy は科学者とエンジニアに 焦点を当てたデータ分析のためのライブラリがインストールされている Python IDE です。
Komodo IDE¶
Komodo IDE はActiveStateによって開発され、 Windows、Mac、Linux用の商用IDEです。 KomodoEdit はオープンソースの代替手段です。
Spyder¶
Spyder は、特に科学的なPythonライブラリ(すなわち、 Scipy )を扱うためのIDEです。 pyflakes、pylint と rope との統合も含まれています。
Spyderはオープンソース(無料)で、コード補完、構文強調表示、クラスと機能のブラウザー、オブジェクト検査を提供します。
WingIDE¶
WingIDE はPython固有のIDEです。 これは、Linux、Windows、Macで動作します(X11アプリケーションとして、一部のMacユーザーを苛立たせます)。
WingIDEは、コード補完、構文強調表示、ソースブラウザ、グラフィカルデバッガ、バージョン管理システムのサポートを提供します。
インタプリタツール¶
仮想環境¶
仮想環境は、プロジェクトパッケージの依存関係を分離する強力な方法を提供します。 つまり、Pythonプロジェクトに特有のパッケージをシステム全体にインストールせずに、バージョン間の競合を避けることができます。
使用を開始し、詳細情報を参照するには: 仮想環境 docs。
pyenv¶
pyenv は複数のバージョンのPythonインタプリタを同時にインストールできるようにするためのツールです。 これにより、Pythonの異なるバージョンを必要とする異なるプロジェクトを持つという問題が解決されます。 たとえば、Python 3.4をデフォルトインタープリタとして使用しながら、あるプロジェクトでPython 2.7を互換性のためにインストールするのは非常に簡単です。 pyenvはCPythonのバージョンだけではなく、PyPy、anaconda、miniconda、stackless、jython、およびironpythonインタープリタもインストールします。
pyenvは shims
ディレクトリにPythonインタプリタの偽のバージョン (pip
や 2to3
などの他のツール) を埋め込むことで動作します。 システムが python
という名前のプログラムを探すと、最初に shims
ディレクトリ内を調べ、偽のバージョンを使用してコマンドをpyenvに渡します。 pyenvは、環境変数、 .python-version
ファイル、およびグローバルデフォルトに基づいてどのバージョンのPythonを実行するかを決定します。
pyenvは仮想環境を管理するツールではありませんが、さまざまな環境の作成を自動化する pyenv-virtualenv プラグインがあります。 既存のpyenvツールを使用して、環境変数や .python-version
ファイルに基づいて異なる環境に切り替えることができます。
Other Tools¶
IDLE¶
IDLE は、Python標準ライブラリの一部である統合開発環境です。 これはPythonで完全に書かれており、Tkinter GUIツールキットを使用しています。 IDLEはPythonを使った本格的な開発には適していませんが、小さなPythonスニペットを試してみて、Pythonのさまざまな機能を試してみることは非常に役に立ちます。
以下の機能を提供します。
- Pythonシェルウィンドウ(インタプリタ)
- Pythonコードを着色するマルチウィンドウテキストエディタ
- 最小限のデバッグ機能
IPython¶
IPython は、Pythonをインタラクティブに使いこなすための豊富なツールキットを提供します。 主なコンポーネントは次のとおりです。
- 強力なPythonシェル(ターミナルおよびQtベース)。
- 同じコア機能を持ちながら、リッチメディア、テキスト、コード、数式、インラインプロットをサポートする ウェブベースのノートブック。インタラクティブなデータの視覚化とGUIツールキットの使用をサポートします。
- 柔軟で埋め込み可能な通訳者が自分のプロジェクトに読み込むことができます。
- 高水準のインタラクティブな並列コンピューティングのためのツール。
$ pip install ipython
IPythonをダウンロードしてインストールするには、ノートブック、qtconsole、テスト、その他の機能のオプションの依存関係が必要です
$ pip install ipython[all]
BPython¶
bpython はUnixライクなオペレーティングシステム用のPythonインタプリタの代替インタフェースです。 それは以下の特徴を有する:
- インライン構文の強調表示。
- 入力時に提案が表示された、読み込みのようなオートコンプリート。
- 任意のPython関数の期待されるパラメータリスト。
- メモリから最後のコード行をポップして再評価する「巻き戻し」機能。
- 入力したコードをペーストビンに送ります。
- 入力したコードをファイルに保存します。
- 自動インデント。
- Python 3のサポート。
$ pip install bpython
ptpython¶
ptpython は、 prompt_toolkit ライブラリの上にあるREPLビルドです。 これは BPython の代わりと考えられています。 機能は次のとおりです。
- シンタックスハイライト
- オートコンプリート
- マルチライン編集
- EmacsとVIMモード
- あなたのコードの中にREPLを埋め込む
- 構文の検証
- タブページ
IPythonをインストールすることで、IPython のシェルとの統合をサポートします。
pip install ipython
と ptipython
を実行します。
$ pip install ptpython
仮想環境¶
仮想環境は、異なるプロジェクトで必要とされる依存関係を別々の場所に保持するためのツールです。仮想環境は、それらのための仮想的なPython環境を作成することによって実現されます。 「Project Xはバージョン1.xに依存しますが、Project Yは4.xが必要です」というジレンマを解決し、グローバルなサイトパッケージディレクトリをきれいに管理します。
例えば、Django 1.10を必要とするプロジェクトで作業し、Django 1.8を必要とするプロジェクトを維持することもできます。
virtualenv¶
virtualenv は独立したPython環境を作るためのツールです。 virtualenvは、Pythonプロジェクトが必要とするパッケージを使用するために必要なすべての実行可能ファイルを含むフォルダを作成します。
pip経由でvirtualenvをインストールします:
$ pip install virtualenv
基本的な使用法¶
1.プロジェクトの仮想環境を作成します。
$ cd my_project_folder
$ virtualenv venv
virtualenv venv
は現在のディレクトリにPythonの実行可能ファイルを含むフォルダを作成し、他のパッケージをインストールするために pip
ライブラリのコピーを作成します。 仮想環境の名前(この場合、 venv
)は何でもかまいません。 名前を省略すると、カレントディレクトリにファイルが配置されます。
これにより、コマンドを実行したディレクトリの中にPythonのコピーが作成され、venv
という名前のフォルダに置かれます。
Pythonインタプリタ( python2.7
など)を使用することもできます。
$ virtualenv -p /usr/bin/python2.7 venv
または ~/.bashrc
のenv変数でインタプリタをグローバルに変更してください:
$ export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python2.7
2.仮想環境の使用を開始するには、仮想環境をアクティブにする必要があります。
$ source venv/bin/activate
現在の仮想環境の名前がプロンプトの左側に表示されます(例えば (venv)Your-Computer:your_project UserName $)
)。 これからpipを使ってインストールしたパッケージは、グローバルなPythonインストールから隔離された venv
フォルダに置かれます。
パッケージを通常どおりにインストールします。例:
$ pip install requests
3.仮想環境で作業が完了した場合は、仮想環境を非アクティブにすることができます。
$ deactivate
これにより、インストールされているすべてのライブラリを持つ、システムのデフォルトのPythonインタプリタに戻ります。
仮想環境を削除するには、そのフォルダを削除するだけです。 (この場合、 rm -rf venv
となります。)
しかし、しばらくすると、システム全体に散在する多くの仮想環境に陥る可能性があり、名前や場所などを忘れる可能性があります。
その他の注意事項¶
--no-site-packages
オプションで virtualenv
を実行すると、グローバルにインストールされたパッケージは含まれません。 後でアクセスする必要がある場合に備えてパッケージリストをきれいに保つのに便利です。 [これは1.7以降の virtualenv
のデフォルト動作です。]
環境の一貫性を保つために、環境パッケージの現在の状態を「フリーズ」することは良い考えです。 これを行うには、
$ pip freeze > requirements.txt
これにより requirements.txt
ファイルが作成されます。このファイルには、現在の環境内のすべてのパッケージとそれぞれのバージョンの単純なリストが含まれています。 “pip list”を使用して、インストールされたパッケージのリストを要件書式なしで見ることができます。 後で同じバージョンを使用して同じパッケージをインストールするために、別の開発者(または環境を再作成する必要がある場合)が簡単になります。
$ pip install -r requirements.txt
これにより、インストール全体、展開全体、および開発者間の一貫性を確保できます。
最後に、ignoreリストに仮想環境フォルダを追加することによって、仮想環境フォルダをソース管理から除外することを忘れないでください。
virtualenvwrapper¶
virtualenvwrapper は、仮想環境での作業をはるかに楽にする一連のコマンドを提供します。 また、すべての仮想環境を1か所に配置します。
インストールするには(virtualenv が既にインストールされていることを確認してください):
$ pip install virtualenvwrapper
$ export WORKON_HOME=~/Envs
$ source /usr/local/bin/virtualenvwrapper.sh
(Full virtualenvwrapperのインストール手順.)
Windowsの場合、 virtualenvwrapper-win を使うことができます。
インストールするには(virtualenv が既にインストールされていることを確認してください):
$ pip install virtualenvwrapper-win
Windowsでは、WORKON_HOME のデフォルトパスは %USERPROFILE%Envs です。
基本的な使用法¶
1.仮想環境を作成します。
$ mkvirtualenv venv
これは ~/Envs
の中に venv
フォルダを作成します。
2.仮想環境での作業:
$ workon venv
あるいは、仮想環境を作成するプロジェクトを作ることもできますし、 $PROJECT_HOME
の中にプロジェクトディレクトリを作ることもできます。これは workon myproject
を実行するときに cd
されます。
$ mkproject myproject
virtualenvwrapper は環境名にタブ補完を提供します。 多くの環境があり、名前を覚えていないときには本当に役に立ちます。
workon
は現在の環境を無効にするので、すばやく環境を切り替えることができます。
3.非アクティブ化はまだ同じです:
$ deactivate
4.削除するには:
$ rmvirtualenv venv
その他の便利なコマンド¶
lsvirtualenv
- すべての環境をリストします。
cdvirtualenv
- 現在アクティブ化されている仮想環境のディレクトリに移動します。たとえば
site-packages
を参照できます。
cdsitepackages
- 上記と同様ですが、
site-packages
ディレクトリに直接入ります。
lssitepackages
site-packages
ディレクトリの内容を表示します。
virtualenv-burrito¶
virtualenv-burrito を使うと、単一のコマンドでvirtualenv + virtualenvwrapper環境を利用することができます。
PipとVirtualenvの詳細設定¶
pip
にアクティブな仮想環境が必要です¶
今では、仮想環境を使用すると、開発環境をきれいに保ち、異なるプロジェクトの要件を別々に保つことができます。
多くの異なるプロジェクトで作業を開始すると、特定のプロジェクトに戻ったときに関連する仮想環境をアクティブにすることを覚えにくくなる可能性があります。 その結果、プロジェクトの仮想環境用のパッケージを実際にインストールしていると考えながら、パッケージをグローバルにインストールするのは非常に簡単です。 時間が経つにつれて、これは不吉なグローバルパッケージリストになる可能性があります。
pip install
を使うときにあなたのアクティブな仮想環境にパッケージをインストールするために、あなたの ~/.bashrc
ファイルに次の行を追加することを検討してください:
export PIP_REQUIRE_VIRTUALENV=true
この変更を保存し、 ~/.bashrc
ファイルを source ~/.bashrc
で取得した後、仮想環境にいない場合、pipはインストールできなくなります。 仮想環境の外側で pip install
を実行しようとすると、パッケージをインストールするためには、起動された仮想環境が必要であることを丁寧に思い出させます。
$ pip install requests
Could not find an activated virtualenv (required).
pip.conf
または pip.ini
ファイルを編集することで、この設定を行うこともできます。 pip.conf
はUnixとMac OS Xのオペレーティングシステムで使われています。
$HOME/.pip/pip.conf
同様に、pip.ini
ファイルはWindowsオペレーティングシステムで使用されています。
%HOME%\pip\pip.ini
これらの場所に pip.conf
または pip.ini
ファイルがない場合は、オペレーティングシステムの正しい名前で新しいファイルを作成することができます。
すでに設定ファイルがある場合は、[global]
の設定の下に次の行を追加して、アクティブな仮想環境が必要になります:
require-virtualenv = true
設定ファイルがない場合は、新しいファイルを作成し、次の行をこの新しいファイルに追加する必要があります:
[global]
require-virtualenv = true
もちろん、いくつかのパッケージをグローバルにインストールする必要があります(通常は異なるプロジェクト間で一貫して使用するパッケージをインストールする必要があります) ~/.bashrc
ファイルに以下を追加することで実現できます:
gpip() {
PIP_REQUIRE_VIRTUALENV="" pip "$@"
}
変更を保存して ~/.bashrc
ファイルを入手したら、gpip install
を実行してパッケージをグローバルにインストールできます。 関数の名前を好きなものに変更することができます。pipを使ってパッケージをグローバルにインストールしようとするときにその名前を使用する必要があることに留意してください。
将来の使用のためのパッケージのキャッシュ¶
すべての開発者は優先ライブラリを持っており、多くの異なるプロジェクトで作業しているときは、使用するライブラリ間で重複することになります。 たとえば、多くの異なるプロジェクトで requests
ライブラリを使用しているかもしれません。
新しいプロジェクト(および結果として新しい仮想環境)での作業を開始するたびに、同じパッケージ/ライブラリを再ダウンロードする必要はありません。 幸いにも、既にインストールされているパッケージを再利用するようにpipを設定することができます。
UNIXシステムでは、次の行を .bashrc
または .bash_profile
ファイルに追加することができます。
export PIP_DOWNLOAD_CACHE=$HOME/.pip/cache
パスを好きな場所に設定することができます(書き込みアクセス権がある限り)。 この行を追加した後、 .bashrc
(または .bash_profile
)ファイルを source
して、あなたはすべて設定されます。
同じ設定を行う別の方法は、あなたのシステムに応じて pip.conf
または pip.ini
ファイルを使用することです。 Windowsの場合は、 [global]
設定の下で pip.ini
ファイルに以下の行を追加することができます:
download-cache = %HOME%\pip\cache
同様に、UNIXシステムでは、[global]
設定の下で pip.conf
ファイルに以下の行を追加するだけです:
download-cache = $HOME/.pip/cache
キャッシュを保存するのに好きなパスを使用することはできますが、pip.conf
または pip.ini
ファイルが存在するフォルダ 内 に新しいフォルダを作成することをお勧めします。 あなたがこのおまじないのパスのすべてを信頼しない場合は、ここで提供されている値を使用すれば問題ありません。
その他の注意事項¶
本書のこのパートは、主に散文であり、Python に関する背景情報から始まり、次のステップに焦点を当てています。
導入¶
PythonはTcl、Perl、Ruby、Scheme、Javaに似た汎用の高水準プログラミング言語です。主な機能の一部は次のとおりです。
非常に明確で読みやすい構文
Pythonの哲学は、重要な空白で区切られたコードブロックから、分かりにくい句読点の代わりに直感的なキーワードに至るまでの読みやすさに焦点を当てています。
事実上あらゆる作業のための広範な標準ライブラリと第三者モジュール
Pythonは、正規表現、ファイルIO、分数処理、オブジェクトのシリアライズなどのモジュールを含む豊富な標準ライブラリのために、「バッテリー同梱」という言葉で記述されることがあります。
さらに、 Python Package Index は、ユーザがPerlの CPAN と同様に、広く使われるようにパッケージを提出することができます。 Django ウェブフレームワークや 数学のルーチンがセットされた NumPy のような非常に強力なPythonフレームワークとツールのコミュニティが盛んです。
他のシステムとの統合
Pythonは Java libraries と統合することができ、企業のプログラマーが慣れ親しんだ豊富なJava環境で使用することができます。 また、スピードが本質である場合、 CまたはC ++モジュールによって拡張 されます。
コンピュータの普及
PythonはWindows、*nix、およびMacで利用できます。 Java仮想マシンが実行される場所であればどこでも実行できます。リファレンス実装のCPythonは、動作しているCコンパイラがあればどこにでもPythonをもたらすのに役立ちます。
フレンドリーコミュニティ
Pythonには、Wiki、会議、無数のリポジトリ、メーリングリスト、IRCチャンネルなどを管理する活気に満ちた大きな コミュニティ があります。 Pythonコミュニティはこのガイドを書くのにも役立っています!
このガイドについて¶
目的¶
Pythonヒッチハイク・ガイド は、初心者でも熟練のPython開発者にも、Pythonのインストール、設定、および使用に関するベストプラクティスハンドブックを毎日提供するために存在します。
コミュニティによる¶
このガイドは、 Kenneth Reitz によってオープンな方法で設計され維持されています。 これは、コミュニティに役立つという、1つの目的のために役立つコミュニティ主導型の取り組みです。
コミュニティ¶
BDFL¶
Pythonの創始者であるGuido van Rossumは、しばしばBDFL(優しい終身の独裁者)と呼ばれています。
Pythonソフトウェア基盤¶
Pythonソフトウェア財団の使命は、Pythonプログラミング言語の普及促進、保護、進歩、およびPythonプログラマーの多様で国際的なコミュニティの成長をサポートし促進することです。
PEPs¶
PEPは Python拡張提案 です。 Python自体やそれを取り巻く標準の変更について記述しています。
3つの異なるタイプのPEPがあります (PEP 1 で定義されています)。
標準
新しい機能や実装について説明します。
情報
デザイン問題、一般的なガイドライン、またはコミュニティへの情報を記述します。
プロセス
Pythonに関連するプロセスについて説明します。
注目すべきPEP¶
必要な読書とみなされるPEPがいくつかあります:
- PEP 8: Pythonスタイルガイド。
これを読みます。 全部です。 それに従ってください。
- PEP 20: Pythonの禅。
Pythonの背後にある哲学を簡単に説明する19のステートメントのリスト。
- PEP 257: Docstringの規約。
PythonのDocstringに関連するセマンティクスと慣習に関するガイドラインを示します。
The PEP Index を読むことができます。
Pythonカンファレンス¶
Pythonコミュニティの主なイベントは、開発者会議です。 2つの最も注目すべき会議は、米国で開催されているPyConとヨーロッパの同胞であるEuroPythonです。
会議の包括的なリストは pycon.org で管理されています。
Pythonユーザグループ¶
ユーザグループは、Python開発者が集まり、Pythonの興味深いトピックを発表したり話したりする場所です。 ローカルユーザグループのリストは Python Software Foundation Wiki で管理されています。
Pythonを学ぶ¶
初心者¶
The Python Tutorial¶
これは公式のチュートリアルです。それはすべての基本をカバーし、言語と標準ライブラリのツアーを提供します。言語のクイックスタートガイドが必要な方におすすめです。
Python for Beginners¶
thepythonguru.com は、初心者プログラマーに焦点を当てたチュートリアルです。 多くのPythonの概念を深く網羅しています。 また、ラムダ式、正規表現のようなPythonのいくつかの先進的な構成を教えてくれます。 最後に、チュートリアル「Pythonを使用してMySQLデータベースにアクセスする方法」を終了します。
Learn Python Interactive Tutorial¶
Learnpython.orgはPythonを紹介するのに簡単な方法です。 このWebサイトは、人気の Try Ruby ウェブサイトで使用されているのと同じアプローチを採用しています。サイトにはインタラクティブなPythonインタプリタが組み込まれており、Pythonをローカルにインストールすることなくレッスンを進めることができます。
もっと伝統的な本が欲しいなら、Python For You and Me は言語のあらゆる面を学ぶのに最適なリソースです。
Online Python Tutor¶
オンラインPython Tutorは、プログラムの実行方法を段階的に示す視覚的なステップを提供します。 Python Tutorは、コンピュータがプログラムのソースコードの各行を実行するときに何が起こるかを理解することによって、プログラミングプログラミングの基本的な障害を克服するのに役立ちます。
Invent Your Own Computer Games with Python¶
この初心者の本はプログラミング経験のない人のためのものです。 各章には、小さなゲームのソースコードがあり、これらのサンプルプログラムを使用して、どのようなプログラムが「見た目に似ているか」というアイデアを読者に提供するプログラミング概念を実証します。
Hacking Secret Ciphers with Python¶
この本は絶対的な初心者のためのPythonのプログラミングと基本的な暗号を教えています。 この章では、さまざまな暗号のソースコードと、それらを壊す可能性のあるプログラムを提供しています。
Learn Python the Hard Way¶
これは初心者のプログラマーのためのPythonの優れたガイドです。 それは、コンソールからウェブへの “hello world”をカバーしています。
Crash into Python¶
Python for Programmers for 3 Hours とも呼ばれるこのガイドは、他の言語の経験豊かな開発者にPythonのクラッシュコースを提供します。
Dive Into Python 3¶
Dive Into Python 3は、Python 3への飛び込み準備が整っている人にとっては良い本です。Python 2から3に移行している場合、またはすでに別の言語でプログラミングを経験している場合は、良い読書です。
Think Python: コンピュータ科学者のように考える方法¶
Think Pythonは、Python言語を使用してコンピュータサイエンスの基本概念を紹介しようとしています。焦点は、たくさんのエクササイズ、最小限の専門用語、そして各章でデバッグのテーマに専念するセクションを含む本を作成することでした。
Python言語で利用できるさまざまな機能を探求しながら、著者はさまざまなデザインパターンとベストプラクティスを編成しています。
本書には、読者が実際の例にこれらのトピックを適用することによって、本で議論されたトピックをより詳細に探究するいくつかのケーススタディも含まれています。ケーススタディにはGUIとMarkov Analysisの課題が含まれています。
Python Koans¶
Python KoansはEdgecaseのRuby Koansのポートです。 テスト駆動型アプローチTEST DRIVEN DESIGN SECTION参照を使用して、基本的なPythonの概念を指導するインタラクティブなチュートリアルを提供します。テストスクリプトで失敗するアサーションステートメントを修正することで、これはPythonを学習するための逐次的な手順を提供します。
言語に慣れていて、自分でパズルを理解している人にとって、これは楽しい、魅力的な選択肢になります。 Pythonとプログラミングの初心者にとっては、追加のリソースやリファレンスを持つことが役に立ちます。
テスト駆動開発の詳細については、次のリソースを参照してください。
Learn to Program in Python with Codeacademy¶
絶対的なPython初心者のためのCodeacademyコース。 この無料でインタラクティブなコースは、進行状況の間のユーザの知識をテストしながら、Pythonプログラミングの基礎(およびそれ以上)を提供し、教えます。 このコースには、あなたの学習に関する即時のフィードバックを受け取るためのビルトイン通訳もあります。
中級¶
Effective Python¶
この本には、Pythonコードの書き方を改善するための59の具体的な方法が含まれています。 227ページでは、効率的な中間レベルのPythonプログラマーになるためにプログラマーが必要とする、最も一般的なコモンズのいくつかの概要を簡単に紹介しています。
上級¶
Expert Python Programming¶
エキスパートPythonプログラミングは、Pythonプログラミングのベストプラクティスを扱い、より高度な群衆に焦点を当てています。
デコレータ(キャッシング、プロキシ、コンテキストマネージャのケーススタディ)、メソッド解決の順序、super() とメタプログラミング、general PEP 8 のベストプラクティスのようなトピックから始まります。
zc.buildoutの使用に関する章を含むパッケージと最終的にアプリケーションの作成とリリースに関する詳細な複数章のケーススタディがあります。後の章では、ドキュメント作成、テスト駆動開発、バージョン管理、最適化とプロファイリングなどのベストプラクティスについて詳しく説明します。
A Guide to Python’s Magic Methods¶
これは、Pythonで ‘特殊メソッド’ を説明するRafe Kettlerのブログ投稿集です。 マジックメソッドは二重のアンダースコア (__init__) で囲まれており、クラスとオブジェクトを違ったやり方で動作させることができます。
注釈
Rafekettler.comは現在ダウンしています。Githubのバージョンに直接行くことができます。ここでPDFバージョンを見つけることができます:
エンジニアと科学者のため¶
A Primer on Scientific Programming with Python¶
Hans Petter Langtangenによって書かれたPythonによる科学プログラミングの入門書は、主に科学分野におけるPythonの使用法をカバーしています。この本では、数学や自然科学の例を選択しています。
Numerical Methods in Engineering with Python¶
Jaan Kiusalaasによって書かれたPythonを使った工学の数値的方法は、数値的方法とPythonでそれらを実装する方法を重視しています。
その他のトピック¶
Problem Solving with Algorithms and Data Structures¶
アルゴリズムとデータ構造による問題解決は、さまざまなデータ構造とアルゴリズムをカバーしています。 すべてのコンセプトは、ブラウザで直接実行できるインタラクティブサンプルとともに、Pythonコードで説明されています。
Programming Collective Intelligence¶
集合知プログラミングは、幅広い基本的な機械学習およびデータマイニング手法を導入しています。解説は、数学的に正式な形式ではなく、基本的な直感を説明することに焦点を合わせ、Pythonでアルゴリズムを実装する方法を示します。
Transforming Code into Beautiful, Idiomatic Python¶
美しく、慣用的なコードに変換するPythonはRaymond Hettingerのビデオです。 Pythonの優れた機能をより有効に活用し、既存のコードを一連のコード変換で改善する方法を学んでください。
Fullstack Python¶
Fullstack Pythonは、Pythonを使用したWeb開発のための完全なトップからボトムのリソースを提供します。
ウェブサーバーの設定から、フロントエンドの設計、データベースの選択、最適化/スケーリングなど
名前が示すように、完全なWebアプリケーションを構築して最初から実行するために必要なものすべてを網羅しています。
参考文献¶
Python in a Nutshell¶
Alex Martelliによって書かれたPython in a Nutshellは、シンタックスから組み込みのライブラリ、Cエクステンションの作成などの高度なトピックまで、ほとんどのクロスプラットフォームPythonの使い方をカバーしています。
Python Essential Reference¶
David Beazleyによって書かれたPython Essential Referenceは、Pythonの決定的なリファレンスガイドです。 これは、標準ライブラリの中核言語と最も重要な部分の両方を簡潔に説明します。 Python 3および2.6のバージョンについて説明します。
Python Pocket Reference¶
Mark Lutzによって書かれたPython Pocket Referenceは、よく使われるモジュールとツールキットについての説明とともに、コア言語への参照を使いやすくしています。 Python 3および2.6のバージョンについて説明します。
Python Cookbook¶
David BeazleyとBrian K. Jonesによって書かれたPython Cookbookには実用的なレシピが満載です。 この本では、コアとなるPython言語、およびさまざまなアプリケーションドメインに共通するタスクについて説明します。
Writing Idiomatic Python¶
Jeff Knuppによって書かれた “Writing Idiomatic Python” には、指摘と理解を最大限にする形式で最も一般的で重要なPythonイディオムが含まれています。 各イディオムは、一般的に使用されているコードを書く方法の推奨として提示され、そのイディオムがなぜ重要であるかについての説明が続きます。 また、イディオムごとに2つのコードサンプルが含まれています。「有害な」書き方と「慣用的な」方法です。
ドキュメンテーション¶
Read the Docs¶
Read the Docsは、オープンソースソフトウェアのドキュメントをホストする一般的なコミュニティプロジェクトです。 一般的なものとエキゾチックなものの両方のPythonモジュールのドキュメントがあります。
ニュース¶
Pycoder’s Weekly¶
Pycoder’s Weeklyは、Python開発者(プロジェクト、記事、ニュース、ジョブ)によるPython開発者向けの無料の週刊Pythonニュースレターです。
Import Python Weekly¶
Pythonの記事、プロジェクト、ビデオ、ツイートをあなたの受信トレイに配信するウィークリーのPythonニュースレター。 あなたのPythonプログラミングスキルを更新しておいてください。
注釈
全音階および半音の音階で定義された備考は、追加の備考のリストからは意図的に除外されています。この備考を付け加える。
寄稿と法的情報(興味がある人向け)。
寄稿¶
Pythonガイドは積極的に開発されており、寄稿者も大歓迎です。
機能のリクエスト、提案、またはバグレポートがある場合は、GitHub で新しい問題を開いてください。 パッチを提出するには、GitHub でプルリクエストを送信してください。 変更がマージされると、自動的に コントリビュータ一覧 に追加されます。
スタイルガイド¶
すべての貢献については、 guide-style-guide に従ってください。
Todoリスト¶
あなたが貢献したいのであれば、たくさんのことがあります。 ここに短い todo リストがあります。
- “これを使用” と “代替案は...” 推奨事項を確立します
課題
青写真について書く
(元のエントリ は、 /home/docs/checkouts/readthedocs.org/user_builds/python-guideja/checkouts/latest/docs/scenarios/admin.rst の 453 行目です)
課題
“コードをフリーズする” スタブを記入
(元のエントリ は、 /home/docs/checkouts/readthedocs.org/user_builds/python-guideja/checkouts/latest/docs/shipping/freezing.rst の 60 行目です)
課題
最も基本的な .exeのステップを書く
(元のエントリ は、 /home/docs/checkouts/readthedocs.org/user_builds/python-guideja/checkouts/latest/docs/shipping/freezing.rst の 108 行目です)
課題
リストされた各プロジェクトの模範的なコードのコード例を含みます。 それが優れたコードである理由を説明してください。 複雑な例を使用します。
(元のエントリ は、 /home/docs/checkouts/readthedocs.org/user_builds/python-guideja/checkouts/latest/docs/writing/reading.rst の 86 行目です)
課題
データ構造、アルゴリズムを迅速に特定し、コードが何をしているのかを判断するためのテクニックを説明します。
(元のエントリ は、 /home/docs/checkouts/readthedocs.org/user_builds/python-guideja/checkouts/latest/docs/writing/reading.rst の 90 行目です)
ライセンス¶
このガイドは、Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unportedライセンス のライセンスを受けています。
ガイドスタイルガイド¶
すべてのドキュメンテーションと同様に、一貫したフォーマットを使用すると、ドキュメントがわかりやすくなります。ガイドをダイジェストしやすくするために、すべての寄稿はこのスタイルガイドのルールの中に適切に収まる必要があります。
ガイドは reStructuredText と書かれています。
注釈
ガイドの一部がこのスタイルガイドとまだ一致していない可能性があります。 これらの部分をガイドスタイルガイドと同期して更新してください。
注釈
レンダリングされたHTMLのどのページでも、「ソースの表示」をクリックして、著者がページのスタイルをどのようにしているかを見ることができます。
関連性¶
ガイドの目的 に関連する貢献を維持してください。
- Python開発に直接関係しない科目に関する情報をあまりにも多く含むことは避けてください。
- 既に情報がある場合は、他の情報源にリンクすることをお勧めします。 何がなぜあなたがなぜリンクしているのかを記述してください。
- サイト は必要に応じて参照してください。
- サブジェクトがPythonに直接関係しないが、Python(例えば、Git、GitHub、Databases)と連動して役に立つ場合、有用なPythonになぜ役に立つのかを説明します。
- 不確かな場合は、尋ねてください。
見出し¶
見出しには次のスタイルを使用します。
章のタイトル:
#########
Chapter 1
#########
ページタイトル:
===================
Time is an Illusion
===================
セクション見出し:
Lunchtime Doubly So
-------------------
サブセクション見出し:
Very Deep
~~~~~~~~~
散文¶
テキスト行を78文字で囲みます。 必要に応じて、行が78文字を超える場合があります。特に、折り返しをするとソーステキストを読みにくくする可能性があります。
シリアルカンマ (オックスフォードカンマとしても知られています)の使用は100%非オプションです。 シリアルカンマがないコンテンツを提出しようとすると、全体の判断が不足し完了するため、このプロジェクトは永久に追放することになります。
追放? それは冗談ですか? うまくいけば、私たちは決して見つけ出す必要はありません。
コード例¶
水平スクロールバーを避けるには、すべてのコード例を70文字で囲みます。
コマンドラインの例:
.. code-block:: console
$ run command --help
$ ls ..
各行の前に $
接頭辞を必ず付けてください。
Pythonインタプリタの例:
Label the example::
.. code-block:: python
>>> import this
Pythonの例:
Descriptive title::
.. code-block:: python
def get_answer():
return 42
外部リンク¶
リンク時によく知られている主題(例:固有名詞)のラベルを優先する:
SphinxはPythonを文書化するために使用されます。
空のリンクを残す代わりに、インラインリンクの説明ラベルを使用することをお勧めします。
Read the `Sphinx Tutorial <http://sphinx.pocoo.org/tutorial.html>`_
- 記述ラベル(SEOにふさわしい)を好む代わりに、「ここをクリック」、「これ」などのラベルを使用しないでください。
ガイドのセクションへのリンク¶
このドキュメントの他の部分を相互参照するには、 :ref: キーワードとラベルを使用してください。
参照ラベルをより明確かつユニークにするには、常に -ref
接尾辞を追加します:
.. _some-section-ref:
Some Section
------------
注釈と警告¶
注釈を作るときは、適切な 警告指令 を利用してください。
注釈:
.. note::
銀河ヒッチハイク・ガイドには、タオルのテーマについていくつかのことが言及されています。 タオルは、星間のヒッチハイカーが持つことができる最も大規模で有用なものであると言います。
警告:
.. warning:: パニックに陥らないでください
TODOs¶
ガイドの不完全な部分は、 todo directive でマークしてください。 todo-list-ref が乱雑にならないようにするには、スタブドキュメントや大規模な不完全セクションに対しては単一の todo
を使います。
.. todo::
生命、宇宙、そしてすべての究極の質問への究極の答えを学ぶ