Your SlideShare is downloading. ×
0
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Python4PHPer - PHPユーザのためのPython入門 (Python2.5)

5,590

Published on

PHPユーザのためのPython入門です。PHPのコードとPythonのコードを並べて書いてるので、PHPユーザにとっては学習しやすいと思います。なお昔の資料なので、Pythonのバージョンが2.5であることに注意。

PHPユーザのためのPython入門です。PHPのコードとPythonのコードを並べて書いてるので、PHPユーザにとっては学習しやすいと思います。なお昔の資料なので、Pythonのバージョンが2.5であることに注意。

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,590
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
18
Comments
0
Likes
5
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. PHPユーザのためのPython入門 Python4PHPer 第08回講習会 2010-10-03(Sun) 日付 1
  • 2. 概要と特徴 2
  • 3. 概要 ✤ 動的なスクリプト言語 ✤ 世界中で人気(特にヨーロッパ) ✤ 作者:Guido van Rossum(Google) ✤ http://www.python.org/ 3
  • 4. 長所 ✤ 簡潔な言語仕様と読みやすい構文 ✤ 強力な機能と豊富なライブラリ ✤ 豊富なドキュメント(日本語訳あり) ✤ 組織立った開発&明確なスケジュール ✤ Windowsを公式にサポート 4
  • 5. 実績 ✤ YouTube(Webサイト全般) ✤ Google(社内システム、Google AppEngine) ✤ RedHat Linux (インストーラ, パッケージ管理システム) ✤ Maya (ハイエンド3DCGソフト) ✤ Blender (3Dモデリング・レンダリングソフト) ✤ ERP5 (基幹業務パッケージ) ✤ BitTorrent (P2P通信ソフト) ✤ Skencil (ドローソフト) ✤ Mercurial, Bazaar (バージョン管理システム) ✤ 他多数 ✤ ✤ http://www.python.org/about/success/ http://ja.wikipedia.org/Pythonを使っている製品あるいはソフトウェアの一覧 5
  • 6. 特徴(対PHP) ✤ 見た目がきれい ✤ インデントを使った構文(見た目=意味) ✤ 行末の「;」がいらない ✤ 「$var」ではなく「var」 ✤ 「$this->method()」ではなく「self.method()」 ✤ 「array(10,20,30)」ではなく「[10, 20, 30]」 ✤ 「array('one'=>1)」ではなく「{'one':1}」 6
  • 7. 特徴(対PHP) ✤ 本格的な言語仕様 ✤ オブジェクト指向 (多重継承あり、インターフェースなし) ✤ 関数オブジェクト、クロージャ ✤ 例外機能 (finallyあり) ✤ 名前空間(パッケージ、モジュール) ✤ イテレータ、ジェネレータ 7
  • 8. 特徴(対PHP) ✤ その他 ✤ 汎用言語 (Webアプリに限定されない) ✤ 配列と辞書とが別のデータ構造 ✤ インタラクティブシェルが標準機能 ✤ JavaScripと類似点が多い ✤ 他の人からバカにされない ✤ 国内では仕事がない 8
  • 9. 日本語ドキュメント ✤ Python和訳ドキュメント ✤ ✤ ✤ http://www.python.jp/doc/   (ダウンロードするなら「Windows Help (chm)」がオススメ) 主要ドキュメント: チュートリアル、ライブラリリファレンス、 言語仕様リファレンス コーディング規約 ✤ PEP 8: Style Guide for Python Code (日本語訳) http://oldriver.org/python/pep-0008j.html ✤ Google Python スタイルガイド(日本語訳) http://works.surgo.jp/translation/pyguide.html 9
  • 10. インストールと起動 10
  • 11. Windows ✤ http://www.python.org/download/releases/2.5.4/ から 「python-2.5.4.msi」をダウンロードしてインストール ✤ ✤ ✤ 標準では C:Python25 にインストールされる 環境変数 %PATH% に C:Python25 を追加するとよい 例: set PATH=%PATH%;C:Python25 PyScripter(Python用IDE)をインストール http://mmm-experts.com/Products.aspx?ProductId=4   から左メニューの「Download」をクリック 注: Google AppEngine が 2.5 系のため、本稿では 2.5 系列を使う 11
  • 12. MacOS X ✤ 標準で Python がインストール済み(だけど、バージョン が違う) ✤ MacPorts でインストール $ sudo port install python 25 $ sudo python_select python25 $ which python /opt/local/bin/python $ python -V Python 2.5.4 ✤ $HOME/.bashrc に「alias py=python」を追加 注: Google AppEngine が 2.5 系のため、本稿では 2.5 系列を使う 12
  • 13. 自前でコンパイル $ wget http://www.python.org/ftp/python/2.5.5/Python-2.5.5.tar.bz2 $ tar xjf Python-2.5.5.tar.bz2 $ cd Python-2.5.5 $ ./configure --prefix=/usr/local/python/2.5.5 $ make $ sudo make install $ export PATH=/usr/local/python/2.5.5/bin:$PATH $ which python /usr/local/python/2.5.5/bin/python $ alias py=python $ cat >> $HOME/.bashrc export $PATH=/usr/local/python/2.5.5/bin:$PATH alias py=python ^D 注: Google AppEngine が 2.5 系のため、本稿では 2.5 系列を使う 13
  • 14. 起動 スクリプト名を指定して起動 $ python example.py # または py example.py スクリプト名を指定せずに起動(インタラクティブシェル) $ python # または py >>> 1 + 1 2 >>> exit() # または Control+D または $ ipython # より高機能なインタラクティブシェル 14
  • 15. エラーがあったら >>> name = "Haruhi" ファイル名と行番号 >>> namae Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'namae' is not defined 例外クラスとエラーメッセージ • エラーが発生したら、いちばん下のメッセージを 見ること 15
  • 16. 主な例外クラス ✤ SyntaxError : 文法が間違っている、またはコードに日本語が含まれて いるのに「# -*- coding: utf-8 -*-」がない ✤ NameError : 変数名や関数名を間違えている ✤ TypeError : データや引数の数または型が間違っている ✤ ValueError : 型は正しいが値として間違っている ✤ AttributeError : 属性名やメソッド名を間違えている、 または変数の値がNoneである ✤ UnicodeEncodeError : ユニコード関連のエラー ✤ KeyError : 辞書のキーが存在しない ✤ IndexError : リストやタプルで添字が範囲外 ✤ IOError : ファイルが存在しない、またはアクセス許可がない ✤ ImportError : モジュール名を間違えている 16
  • 17. サンプルプログラム 【関連ドキュメント】 • チュートリアル: 3. 形式ばらない Python の紹介 http://www.python.jp/doc/release/tut/node5.html 17
  • 18. コメント PHP // 行コメント # 行コメント /* 範囲コメント */ • 「//」と「#」が行コメ ント • 「/* */」が範囲コメント Python # -*- coding: utf-8 -*# 行コメント マジックコメント (「# coding: utf-8」でも可) • 「#」が行コメント • 範囲コメントはなし • 日本語を含める時はマ ジックコメントが必要 18
  • 19. Hello World PHP Python echo "Hello World!n"; • 文末に「;」が必要 • 改行を出力するには 「n」を明示 print "Hello World!" # または import sys sys.stdout.write( "Hello World!n") • 「;」が必要ない • print が自動的に改行を 出力 19
  • 20. Hello World (2) PHP Python $name = "World"; echo "Hello ", $name, "!n"; echo "Hello $name!"; • 変数に $ をつける • 文字列中に変数を埋め込 める name = "World" print "Hello", name, "!" print "Hello %s!" % name • 変数に prefixをつけない • 文字列中に変数を埋め込 めない 20
  • 21. 奇数だけ出力 PHP $arr = array(1, 2, 3, 4, 5); foreach ($arr as $item) { if ($item % 2 == 1) { echo $item, "n"; } } • 配列はarray() • foreach や if で () が必要  • ブロックは「{ }」で表現 Python list1 = [1, 2, 3, 4, 5] for item in list1: if item % 2 == 1: print item • リストは [] • for や if で () いらず  • ブロックは「:」とインデ ントで表現 21
  • 22. フィボナッチ数列 PHP Python function fib($n) { return $n <= 2 ? 1 : fib(n-1) + fib(n-2); } echo fib(30); • 関数定義は「function」 • 条件演算子は 式 ? 真のとき : 偽のとき def fib(n): return 1 if n <=2 else fib(n-1) + fib(n-2) print fib(30) • 関数定義は「def」 • 条件演算子は 真のとき if 式 else 偽のとき 22
  • 23. データの中身を表示 PHP Python $val = array( "one"=>1, "two"=>2); var_export($val); • 連想配列はarray() • データの中身は var_export() や var_dump() で表示 val = { "one":1, "two": 2 } print repr(val) • 辞書は { } • データの中身は repr() で表現 (なしでもよい) 23
  • 24. メタプログラミング PHP Python function errmsg($mesg) { $f = fopen("php://stderr", "w"); fwrite($f, $mesg."n"); fclose($f); } $func = 'errmsg'; $func("ERROR"); import sys sys.stderr.write("ERRORn") write = sys.stderr.write write("ERRORn") • 関数名やメソッド名を表 • メソッドを取り出し、変 す文字列を変数に代入 し、呼び出し可能 x=1 add1 = x.__add__ print add1(3) #=> 4 数に代入可能、かつ呼び 出し可能 24
  • 25. リテラル 【関連ドキュメント】 • 言語仕様リファレンス: 2.4 リテラル (literal) http://www.python.jp/doc/release/ref/literals.html • ライブラリリファレンス: 3. 組み込み型 http://www.python.jp/doc/release/lib/types.html 25
  • 26. 数値 PHP Python 123 # 整数 123 # 整数 077 #=> 63  077 #=> 63  0xFF #=> 255  0xFF #=> 255  3.14 # 小数 3.14 # 小数 1.0e-4   #=> 0.0001 1.0e-4 #=> 0.0001  3+4j # 複素数 pow(2,64) #=> 1.844674407371E+19  2**64 #=> 18446744073709551616L  26
  • 27. 文字列 PHP Python # メタキャラクタ解釈あり # メタキャラクタ解釈あり "strn" "strn" 'strn' # メタキャラクタ解釈なし # メタキャラクタ解釈なし 'strn' r"strn" r'strn' 27
  • 28. 複数行文字列 PHP Python # 複数行文字列 # 複数行文字列 "aaa bbb ccc" """aaa bbb ccc""" 'aaa bbb ccc' r'''aaa bbb ccc''' 「"」3つまたは 「’」3つで囲む 「r」をつける ことも可 28
  • 29. ヒアドキュメント PHP # ヒアドキュメント $string = <<<END aaa bbb ccc END; Python # ヒアドキュメントはなし、 # 複数行文字列を使う string = """ aaa bbb ccc"""[1:] 最初の改行文字を取り 除く(詳細は後述) 29
  • 30. ユニコード PHP # 該当機能なし Python マジックコメント # -*- coding: utf-8 -*"ばけらった" # str u"ばけらった" # unicode ## 変換 u"ば".encode('utf8') # str "ば".decode('utf8') # unicode • マジックコメントがない とSyntaxError • 「# coding: utf-8」でも可 30
  • 31. 真偽値、NULL PHP Python TRUE #真 True #真 FALSE #偽 False #偽 NULL # NULL None # NULL • 大文字・小文字の区別なし • 偽となるのは FALSE, NULL, 0, 空の文字列や配列 • 大文字・小文字の区別あり • 偽となるのは False, None, 0, 空の文字列やリストやタプル や辞書 31
  • 32. 演算子 【関連ドキュメント】 • 言語仕様リファレンス: 5. 式 (expression) http://www.python.jp/doc/release/ref/expressions.html • ライブラリリファレンス: 3. 組み込み型 http://www.python.jp/doc/release/lib/types.html 32
  • 33. 同値判定 PHP "123" == "123" "123" != "123" "0123" == 123 #=> TRUE "0123" === 123 #=> FALSE "0123" === "123" "0123" !=== "123" Python "123" == "123" "123" != "123" "123" == 123 #=> False "123" != "123" u"123" == "123" #=> True • '==' は文字列が数値に変換 • 数値と文字列が勝手に変換 されることがある • '===' は変換せずに比較 されることはない • unicodeは変換される 33
  • 34. 同一判定 Python list1 = [] list2 = [] list1 == list2 list1 is list2 list2 = list1 list1 is list2 #=> True #=> False #=> True • '==' は同値判定、'is' は同一 判定(反対は 'is not') True == 1 True is 1 False == 0 False is 0 None == 0 None is 0 #=> True #=> False #=> True #=> False #=> False #=> False • Trueは1と同値かつ非同一、 Falseは0と同値かつ非同一 34
  • 35. 比較演算子 PHP Python 1>0 1 >= 1 0<1 1 <= 1 1>0 1 >= 1 0<1 1 <= 1 0 < $x && $x < 3 0<x<3 0 < 1 <= 2 == 2 < 3 • 複数の比較は && で連結 • 複数の比較を連結できる 35
  • 36. 論理演算子 PHP !x x && y x || y Python x and y x or y x xor y not x x and y x or y # -- $x = $val or die(); # ($x = $val) or die() と同じ x = val or die() # x = (val or die()) と同じ • 優先度が違う2種類を用意 • '!', '&&', '||' は使えない 36
  • 37. 論理演算子の値 PHP Python 10 && 0 0 || 10 #=> FALSE #=> TRUE $x = $y = ""; $v = $x ?: $y ?: "default"; • 論理演算子の結果は必ず TRUEかFALSE 10 and 0 0 or 10 #=> 0 #=> 10 x = y = "" v = x or y or "default" • 論理演算子の結果がTrueや Falseにならない 37
  • 38. メンバシップ PHP # 該当演算子なし Python 2 in [1, 2, 3] 4 not in [1, 2, 3] "a" in {"a": 10} "b" not in {"a": 10} "ana" in "banana" # True # True # True # True # True • listやtupleやsetの場合は 要素が含まれるか? • dictならキーに含むか? • 文字列なら部分文字列か? 38
  • 39. 算術演算子 PHP 1+1 1-1 1*1 10 / 3 #=> 3.33333333 10 % 3 #=> 1 pow(2, 10) #=> 1024 Python 1+1 1-1 1*1 10 / 3 #=> 3 10 % 3 #=> 1 2**10 #=> 1024 39
  • 40. 結合演算子 PHP "foo" . "bar" #=> "foobar" Python "foo" + "bar" u"foo" + u"bar" u"foo" + "bar" "foo" + u"bar" # str # unicode # unicode # unicode • ひとつでもunicodeなら結 果もunicode • すべてstrのときだけ結果 もstr 40
  • 41. 代入演算子 PHP $x = 1 $x += 1 $x -= 1 $x *= 1 $x /= 1 $x %= 1 $x .= "str" Python x=1 x += 1 x -= 1 x *= 1 x /= 1 x %= 1 x += "str" 41
  • 42. ビット演算子、シフト演算子 PHP Python $x & 0xFF $x | 0xFF $x ^ 0xFF ~ $x x & 0xFF x | 0xFF x ^ 0xFF ~x $x << 2 $x >> 2 x << 2 x >> 2 42
  • 43. 三項演算子(条件演算子) PHP Python $v = $x > 0 ? $x : - $x; v = (x if x > 0 else - x) $v = $x > 0 ? $x : ($y > 0 ? $y : ($z > 0 ? $z : -9999)); v = (x if x > 0 else y if y > 0 else z if z > 0 else -9999) • 演算子優先順位の問題によ り、つなげるときはカッコ が必要 • Perlの後置記法と間違えな いよう、カッコ推奨 • つなげること自体にはカッ コいらず 43
  • 44. その他 ✤ 演算子オーバーロードが可能 ✤ x++(インクリメント)や x--(デクリメント)は、ない ✤ `shell command` は、ない (import os; os.system("shell command") を使う) 44
  • 45. コンテナ 【関連ドキュメント】 • チュートリアル: 5. データ構造 http://www.python.jp/doc/release/tut/node7.html • ライブラリリファレンス: 3.6.4 変更可能なシーケンス型 http://www.python.jp/doc/release/lib/typesseq-mutable.html • ライブラリリファレンス: 3.8 マップ型 http://www.python.jp/doc/release/lib/typesmapping.html 45
  • 46. リスト (List) PHP Python # 配列 # リスト(更新可能) $arr = array(10, 20, 30,); echo $arr[2]; $arr[] = 40; var_export($arr); list1 = [10, 20, 30,] print list1[2] list1.append(40) print repr(list1) • 実体は連想配列 • 最後の ',' は省略可能 • 連結リストではない • 最後の ',' は省略可能 46
  • 47. リスト: 代入によるコピー PHP Python $arr1 = array(10, 20, 30); $arr2 = $arr1; 配列がコピーされる $arr2[1] = 25; var_export($arr1); #=> array(0=>10, # 1=>20, # 2=>30) # (変更されてない) list1 = [10, 20, 30] list2 = list1 同じリストを共有 list2[1] = 25 print repr(list1) #=> [10, 25, 30] # (変更された!) • コピーは list2 = list1[:] (スライスについては後述) 47
  • 48. リスト: 繰り返し PHP ## 単純ループ foreach ($arr as $x) echo $x; ## カウンタ付きループ foreach ($arr as $i=>$x) echo $i, $x; Python ## 単純ループ for x in list1: print x ## カウンタ付きループ for i, x in enumerate(list1): print i, x 48
  • 49. リスト: 各種操作 Python ## リストの長さ ## 要素の連結 list1 = ['a', 'b', 'c'] print len(list1) #=> 3 print "".join(list1) # 'abc' print ",".join(list1) # 'a,b,c' ## 要素が含まれるかどうか ### 逆順にする (破壊的) print 'b' in list1 #=> True print 'x' in list1 #=> False list1.reverse() print list1 #=> ['c','b','a'] 49
  • 50. リスト: 各種操作 Python ## 要素を追加する (破壊的) ## 添字を指定して追加 (破壊的) list1 = [] list1.append(10) list1.append(20) print list1 #=> [10, 20] list1.insert(3, 'A') print list1 #=> [10, 20, 30, 'A', 40] ## 他のリストを追加 (破壊的) list1.extend([30, 40]) print list1 #=> [10, 20, 30, 40] 50
  • 51. リスト: 各種操作 Python ## 一致する要素の添字を返す list1 = ['a','b','c','b'] print list1.index('b') #=> 1 print list1.index('x') #=> ValueError ## 一致する要素の数を返す print list1.count('b') #=> 2 51
  • 52. リスト: 各種操作 Python ## 一致する最初の要素を取り除く (破壊的) list1 = [3, 1, 4, 1, 5, 9] list1.remove(1) print list1 #=> [3,4,1,5,9] list1.remove(999) #=> ValueError ## 最後の要素を取り除いて返す (破壊的) print list1.pop() #=> 9 print list1 #=> [3,4,1,5] [].pop() #=> IndexError 52
  • 53. リスト: 各種操作 Python ## ソート (破壊的) ## 逆順ソート (破壊的) list1 = [3, 1, 4, 1, 5, 9] list1.sort() print list1 #=> [1, 1, 3, 4, 5, 9] list1.sort(reverse=True) print list1 #=> [9, 5, 4, 3, 1, 1] ## ソート (非破壊的) list1 = [3, 1, 4, 1, 5, 9] list2 = sorted(list1) print list2 #=> [1, 1, 3, 4, 5, 9] print list1 #=> [3, 1, 4, 1, 5, 9] ## 要素を指定したソート (破壊的) list2 = [['A',3], ['B',1], ['C',2]] list2.sort(key=lambda x: x[1]) print list2 #=> [['B', 1], ['C', 2], ['A', 3]] 53
  • 54. タプル (Tuple) ✤ タプル (tuple) ✤ 変更できないリスト ✤ リストより軽量 ✤ 辞書のキーに指定可能 ✤ リストと同じ操作が可能 (非破壊操作のみ) Python # タプル(更新不可) tuple1 = (10, 20, 30) print tuple1[2] tuple1[2] = 31 #=> TypeError print repr(tuple1) var = (9) # 整数値 var = (9, ) # タプル var = () # 空タプル 54
  • 55. 辞書 (Dictionary) PHP # 連想配列 $arr = array("a"=>1, "b"=>2); Python echo $arr["b"]; #=> 2 $arr["c"] = 3; # 辞書 dict1 = {"a":1, "b":2 } # or dict1 = dict(a=1, b=2) print dict1["b"] #=> 2 dict1["c"] = 3 var_export($arr); #=> array('a'=>1,'b'=>2,'c'=>3) print dict1 # or repr(dict1) #=> {'a': 1, 'c': 3, 'b': 2} • 順番が保存される • 順番は保存されない 55
  • 56. 辞書: キーが存在しないとき PHP Python $arr = array('A'=>1, 'B'=>2); echo $arr['A']; echo $arr['X']; #=> NULL dict1 = {'A':1, 'B':2} print dict1['A'] print dict1['X'] #=> KeyError echo isset($arr['X']) ? $arr['X'] : 10; print dict1.get('X', 10) #=> 10 print dict1.get('X') #=> None • キーが存在しないときは • キーが存在しないときは NULL (Warningも出る) • キーがないときのデフォル ト値を指定する方法なし KeyErrorが発生 • dict.get()でキーがないとき のデフォルト値を指定可能 56
  • 57. 辞書: 繰り返し PHP Python foreach ($arr as $key=>$val) echo $key, $val; for key, val in dict1.iteritems(): print key, val foreach ($arr as $item) echo $item; # 値 for item in dict1: print item # キー • 「as $key=>$val」なら キーと値の繰り返し • 「as $val」なら値の繰返し • dict.iteritems()を使う • 使わない場合はキーの繰り 返し (dict.iterkeys()推奨) 57
  • 58. 辞書: 各種操作 Python ## 要素の数 dict1 = {'A':1, 'B':2} print len(dict1) #=> 2 ## キーが存在するかどうか print dict1.has_key('A') print 'A' in dict1 ## すべてのキーを取り出す print dict1.keys() #=>['A','B'] ## 要素を削除 (破壊的) del dict1['A'] print dict1 #=> {'B':2} del dict1['C'] #=> KeyError ## すべての値を取り出す print dict1.values() #=> [1,2] 58
  • 59. 辞書: 各種操作 Python ## コピー dict1 = {'A': 1, 'B': 2} dict2 = dict1.copy() print dict2 #=> {'A': 1, 'B': 2} ## キーを指定して削除 (破壊的) print dict2.pop('C') #=> 3 print dict2.pop('C') #=> KeyError print dict2.pop('C', 3) #=> 3 ## 別の辞書で更新 (破壊的) dict2.update({'C':3}) print dict2 #=> {'A': 1, 'C': 3, 'B': 2} ## すべてを削除 (破壊的) dict2.clear() print dict2 #=> {} 59
  • 60. 辞書: 各種操作 Python ## キーがないときだけ値を追加 dict1 = {'A':1, 'B':2} dict1.setdefault('C', 3) # 'C' はないので追加され、かつ 3 が返される dict1.setdefault('C', 9) # 'C' はあるので追加されず、かつ # dict['C'] が返される ## 使い道:たとえばこれが if 'key' not in dict1: dict1['key'] = [] dict1['key'].append('val') ## こう書ける dict1.setdefault('key', []).append('val') 60
  • 61. 集合 (Set) ✤ Python set  ✤ ✤ 順序を持たない ✤ 値の重複を許さない ✤ 変更可能 ✤ ✤ 値の集まり 辞書のキーに指定可能な値 のみ受け付ける frozenset  リストや 辞書は不可 ✤ 変更不可なset ✤ # 集合 (set) set1 = set(['a', 'b']) print set1 #=> set(['a', 'b']) # 順序を持たない set1.add('c') print set1 #=> set(['a', 'c', 'b']) # 値の重複を許さない set1.add('a') print set1 #=> set(['a', 'c', 'b']) 辞書のキーに指定可能 61
  • 62. 集合: よくある例 Python ## リストを使った判定(遅い) members = ['Haruhi', 'Mikuru', 'Yuki', 'Itsuki', 'Kyon'] for i in xrange(10000): found = 'Tsuruya' in members ## 集合を使った判定(速い) members = set(['Haruhi', 'Mikuru', 'Yuki', 'Itsuki', 'Kyon']) for i in xrange(10000): found = 'Tsuruya' in members 62
  • 63. 集合: 各種操作 Python ## 値を追加 set1 = set(['a', 'b', 'c']) set1.add('d') ## 値があるかどうか 'a' in set1 #=> True 'A' not in set2 #=> True ## 値を削除 set1.remove('d') set1.remove('d') #=> KeyError set1.discard('d') # 値がなくても # 例外を投げない ## 要素数 print len(set1) #=> 3 ## 繰り返し for x in set1: print x, #=> a c b ## 浅いコピー set2 = set1.copy() 63
  • 64. 集合: 各種演算 Python set1 = set(['a', 'b']) set2 = set(['b', 'c']) ## 和集合 (∪) set1 | set2 #=> set(['a','b','c']) ## 積集合 (∩) set1 & set2 #=> set(['b']) ## 差集合 (∪) set1 - set2 #=> set(['a']) ## 対象差 (△) set1 ^ set2 #=> set(['a','c']) ## 包含関係 (⊆、⊇) set3 = set(['a', 'b', 'c']) set4 = set(['b', 'c']) set3 > set4 #=> True set3 < set4 #=> False set3 >= set4 #=> True set3 <= set4 #=> False set3 > set3 #=> False set3 < set3 #=> False set3 >= set3 #=> True set3 <= set3 #=> True 64
  • 65. シーケンス、スライス 【関連ドキュメント】 • ライブラリリファレンス: 3.6 シーケンス型 str, unicode, list, tuple, buffer, xrange http://www.python.jp/doc/release/lib/typesseq.html • 言語仕様リファレンス: 3 スライス表記 (slicing) http://www.python.jp/doc/release/ref/slicings.html 65
  • 66. シーケンスとは? ✤ (主に) リスト、タプル、文字列のこと ✤ どれも同じような操作を提供 Python L = ['a', 'b', 'c', ] # リスト T = ('a', 'b', 'c', ) # タプル S = "abc" # 文字列 # 要素へのアクセス print L[2], T[2], S[2] #=> c c c # 要素の繰り返し for x in L: print x, #=> a b c for x in T: print x, #=> a b c for x in S: print x, #=> a b c 66
  • 67. シーケンス: 操作 Python # 要素があるかどうか print 'b' in L print 'b' in T print 'b' in S # 結合 print L + ['d'] #=> ['a','b','c','d'] print T + ('d',) #=> ('a','b','c','d') print S + "d" #=> 'abcd' # 要素が含まれないか print 'x' not in L print 'x' not in T print 'x' not in S # 長さ print len(L) #=> 3 print len(T) #=> 3 print len(S) #=> 3 67
  • 68. シーケンス: 変換 Python # リストへ変換 print list(T) #=> ['a', 'b', 'c'] print list(S) #=> ['a', 'b', 'c'] # 文字列へ変換 print str(L) #=> "['a', 'b', 'c']" print str(T) #=> "('a', 'b', 'c')" # タプルへ変換 print tuple(L) #=> ('a', 'b', 'c') print tuple(S) #=> ('a', 'b', 'c') # 要素を連結 print "".join(L) print "".join(T) #=> 'abc' #=> 'abc' 68
  • 69. スライス: 部分要素の取り出し Python # -5 -4 -3 -2 -1 # 0 1 2 3 4 L = ['a','b','c','d','e'] # リスト T = ('a','b','c','d','e') # タプル S = "abcde" # 文字列 • L[1:3] なら L[1] と L[2] は含 # 部分要素の取り出し print L[1:3] #=> ['b', 'c'] print T[1:3] #=> ('b', 'c') print S[1:3] #=> 'bc' print L[1:-1] #=> ['b', 'c', 'd'] print T[1:-1] #=> ('b', 'c', 'd') print S[1:-1] #=> 'bcd' まれるが L[3] は含まれない ことに注意 • L[n:m] の長さは m-n • マイナスは後ろから数える 69
  • 70. スライス: 部分要素の変更 Python # 部分要素の変更 L = ['a', 'b', 'c', 'd', 'e'] 型や要素数が異なっ print L[1:3] #=> ['b', 'c'] ていてもよい L[1:3] = ('X', 'Y', 'Z') print L #=> ['a', 'X', 'Y', 'Z', 'd', 'e'] • タプルと文字列は変更不可 (immutable) なので、TypeError になる 70
  • 71. スライス: 添字省略時 Python # 0 1 2 3 4 L = ['a', 'b', 'c', 'd', 'e'] print L[:2] #=> ['a', 'b'] print L[2:] #=> ['c', 'd', 'e'] print L[:] #=> ['a','b','c','d','e'] L == L[:n] + L[n:] # 常に真 L2 = L[:] # 全体のコピー L3 = L # 同じリストを共有 • 最初の添字を省略すると 0 • 最後の添字を省略すると len(L) 71
  • 72. 文字列操作 【関連ドキュメント】 • ライブラリリファレンス: 3.6.1 文字列メソッド http://www.python.jp/doc/release/lib/string-methods.html • チュートリアル: 3.1.2 文字列 http://www.python.jp/doc/release/tut/node5.html#SECTION005120000000000000000 72
  • 73. 文字列操作 Python # 単純結合 'Ha'+'ru'+'hi' #=> 'Haruhi' # 部分文字列 "Haruhi"[2:5] #=> 'ruh' # 複数文字列結合 ''.join(['s', 'o', 's']) #=> 'sos' '/'.join(['s','o','s']) #=> 's/o/s' # 長さ len("Suzumiya") #=> 8 # 繰り返し 'Wa' * 3 #=> 'WaWaWa' # 数値に変換 int("10") #=> 10 int("FF", 16) #=> 255 (16進数) float("3.14") #=> 3.1400000001 73
  • 74. 文字列操作 Python 値が複数ならタプルで指定 # 書式 (printf相当) x, y = 'A', 123 'x=%s, y=%s' % (x, y) # x=A, y=123 '<%5s>' % x # < A> '<%-5s>' % x # <A > '<%5d>' % y # < 123> '<%-5d>' % y # <123 > '<%05d>' % y # <00123> 'pi=%f' % 3.1415 # pi=3.141500 'pi=%7.3f' % 3.1415 # pi= 3.142 'list=%r' % [10,20,30] # list=[10, 20, 30] 'dict=%r' % {'a':10} # dict={'a': 10} 'a=%(a)s, b=%(b)s' % {'a':10,'b':20} # x=10, y=20 'x=%(x)s, y=%(y)s' % locals() # x=A, y=123 74
  • 75. 文字列操作 Python # 部分文字列を検索 "Haruhi".find("uh") #=> 3 "Haruhi".find("x") #=> -1 "Haruhi".index("uh") #=> 3 "Haruhi".index("x") #=> ValueError # 開始文字列をチェック 'Nyoroon'.startswith('Nyo') #=> True # 終了文字列をチェック 'Dounyoro'.endswith('nyoro') #=> True # 逆から検索 "Mikuru".rfind("u") #=> 3 "Mikuru".rindex("u") #=> 5 75
  • 76. 文字列操作 Python # 置換 "Mikuru".replace('ku', 'chi') #=> 'Michiru' # カウント 'kamadouma'.count('ma') #=> 2 # 空白文字の削除 " Kyon ".strip() #=> 'Kyon' " Kyon ".lstrip() #=> 'Kyon ' " Kyon ".rstrip() #=> ' Kyon' # 行に分割 s = """Haruhi Mikuru Yuki """ s.splitlines() #=> ['Haruhi', 'Mikuru', 'Yuki'] s.splitlines(True) #=> ['Haruhin', 'Mikurun', 'Yukin'] 76
  • 77. 文字列操作 Python # 大文字に変換 "yuki".upper() #=> "YUKI" # 小文字に変換 "YUKI".lower() #=> "yuki" # 大文字・小文字を入れ替える "Yuki".swapcase() #=> 'yUKI' # 文字種類の判別 "Endless8".isalnum() #=> True "Endless8".isalpha() #=> False "8".isdigit() #=> True "endless8".islower() #=> True "ENDLESS8".isupper() #=> True " ".isspace() #=> True "End Less Eight".istitle() #=> True 77
  • 78. 文字列操作 Python # キャピタライズ 'yuki'.capitalize() #=> Yuki # 文字列幅の調整 "Yuki".ljust(8, '!') #=> 'Yuki!!!!' "Yuki".rjust(8, '!') #=> '!!!!Yuki' # 単語ごとにキャピタライズ "haruhi mikuru YUKI".title() #=> 'Haruhi Mikuru Yuki' # 頭にゼロを追加 '8'.zfill(3) #=> '008' # 中央 え 'Kyon'.center(10) #=> ' Kyon ' (長さ10) # タブを半角空白に展開 "Nyotroon".expandtabs(8) #=> 'Nyo roon' 78
  • 79. 基本構文 【関連ドキュメント】 • チュートリアル: 4. その他の制御フローツール http://www.python.jp/doc/release/tut/node6.html • 言語仕様リファレンス: 6. 単純文 (simple statement) http://www.python.jp/doc/release/ref/simple.html • 言語仕様リファレンス: 7. 複合文 (compound statement) http://www.python.jp/doc/release/ref/compound.html 79
  • 80. print文 PHP Python $x = 10; $y = 20; echo 'x=', $x, ', y=', $y, "n"; echo "x=$x, y=$yn"; • 改行は"n"で明示 • 引数間に空白は入ら ない x = 10; y = 20 print 'x=', x, ', y=', y print 'x=%s, y=%s' % (x, y) • 自動的に改行される ("," で終わると改行しない) • 引数間に半角空白が入る 80
  • 81. 代入文 PHP Python $x = 0; x=0 $x += 1; x += 1 $x++; # インクリメントはなし # 多重代入 list($x, $y) = array(10, 20); list($x, $y) = array($y, $x); # 多重代入 x, y = 10, 20 # or (10,20) x, y = y, x # or (y, x) 81
  • 82. if文 PHP $x = 0; if ($x > 0) { echo "$x is positivie.n"; } elseif ($x < 0) { echo "$x is negative.n"; } else { echo "$x is zero.n"; } Python x=0 if x > 0: print "%s is positive." % x elif x < 0: print "%s is negative." % x else: print "%s is zero." % x 82
  • 83. while文 PHP Python $i = 0; while (++$i <= 10) { echo $i, "n"; } • do { } while () も利用 i=1 while i <= 10: print i i += 1 • do - while は、なし 可能 83
  • 84. for文 PHP Python $arr = array(10, 20, 30); foreach ($arr as $item) { echo $item, "n"; } list1 = [10, 20, 30] for item in list1: print item for ($i=0; $i<10; $i++) { echo $i, "n"; } for i in xrange(1, 10): print i • for (;;) も利用可能 • for (;;) はないので、 xrange()で代用 (後述) 84
  • 85. break文、continue文 PHP foreach ($arr as $item) { if ($item === NULL) continue; if ($item === 100) { echo "found!n"; break; } } Python for item in list1: if item is None: continue if item == 10: print "found!" break 85
  • 86. pass文 PHP if (! $name) { // TODO: エラー処理 } else { echo $name; } Python if not name: ## TODO: エラー処理 pass else: print name • 何もしないことを表す ためにpass文が必要 86
  • 87. del文 PHP $x = 1; echo $x; #=> 1 unset($x); echo $x; # Notice: undefined variable $arr = array("a"=>123); echo $arr["a"]; #=> 123 unset($arr["a"]); echo $arr["a"] # Notice: Undefined index Python x=1 print x del x print x #=> 1 # NameError dict1 = {"a":123} print dict1["a"] #=> 123 del dict1["a"] print dict1["a"] # KeyError 87
  • 88. else節 PHP $arr = array(1, 2, 3); $found = FALSE; foreach ($arr as $item) { if ($item == 100) { $found = TRUE; break; } } if (! $found) echo "not foundn"; Python list1 = [1, 2, 3] for item in list1: if item == 100: break else: print "not found" • forとwhileにelse節を 追加できる • breakしなかったとき だけelse節を実行 88
  • 89. try文 PHP try { throw new Exception("msg"); } catch (Exception $ex) { echo $ex->message(); } catch (OtherException $ex) { throw $ex; } Python try: raise Exception("msg") except Exception, ex: print ex.message except OtherException, ex: raise finally: print "finally" • finally節が利用可能 89
  • 90. assert文 PHP Python $var = NULL; assert('$var != NULL'); var = None assert var != None # これは次と同等 if __debug__: if not (var != None): raise AssertionError • assert関数の引数は、 • assert 文の引数は、 式を表す文字列 • assert_option() で挙動 を指定できる 式そのもの • Python起動時に -O を 指定すると無視される 90
  • 91. with文 Python Python2.5では必要 from __future__ import with_statement with open('file.txt') as f: for line in f: print line, ## with文が終了した時点で ## fが自動的にクローズされる ## これは次と(だいたい) 同じ f = open('file.txt') f.__enter__() try: for line in f: pirnt line, finally: f.__exit__() • 参照: PEP 0343 The "with" statement 内部でf.close()を実行 http://www.python.org/peps/pep-0343.html 91
  • 92. 内包表記 (list complehension) Python list1 = [1, 2, 3, ] list2 = [ i*i for i in list1 ] print list2 #=> [1, 4, 9] list2 = [ i*i for i in list1 if i % 2 == 1 ] print list2 #=> [1, 9] ## これは次と同等 list2 = [] for i in list1: list2.append(i*i) ## これは次と同等 list2 = [] for i in list1: if i % 2 == 1: list2.append(i*i) • for文より簡潔で高速でわかりやすい • for文は動作の記述、内包表記は意図の記述 92
  • 93. 関数 【関連ドキュメント】 • チュートリアル: 4.7 関数定義についてもう少し http://www.python.jp/doc/release/tut/node6.html#SECTION006700000000000000000 • ライブラリリファレンス:2.1 組み込み関数 http://www.python.jp/doc/release/lib/built-in-funcs.html • 言語仕様リファレンス: 7.6 関数定義 http://www.python.jp/doc/release/ref/function.html 93
  • 94. 関数定義 PHP /** フィボナッチ数を計算 */ function fib($n) { if ($n <= 2) { return 1; } else { return fib($n-1)+fib($n-2); } } echo fib(30); 関数定義の冒頭に記述 Python (構文としてサポート) def fib(n): """フィボナッチ数を計算""" if n <= 2: return 1 else: return fib(n-1)+fib(n-2) print fib(30) help(fib) ドキュメントを表示 94
  • 95. 引数のコピー PHP function f($arr) { $arr[0] = 123; var_export($arr); } $arr = array(10); f($arr); #=> array(0=>123,) var_export($arr); #=> array(0=>10, ) • 引数の配列はコピーされる Python def f(list1): list1[0] = 123 print repr(list1) list1 = [10] f(list1) #=> [123] print repr(list1) #=> [123] • 引数のリストや辞書はコ ピーされない 95
  • 96. デフォルト引数 PHP Python function f($x, $y=0, $z=0) { echo $x, $y, $z; } def f(x, y=0, z=0): print x, y, z function g($a=array()) { $a[] = 1; var_export($a); } 新しい配列が g(); g(); g(); 毎回作成される def g(a=[]): a.append(1) print repr(a) 同じリストが 毎回使われる g(); g(); g() 96
  • 97. キーワード引数 PHP ## 該当機能なし Python ## 仮引数の名前を使って ## 実引数を指定する def f(x, y=0, z=0): return x + y + z ## どれも f(5, 0, 10) と同じ print f(5, z=10) print f(z=10, x=5) 97
  • 98. 可変長引数 PHP function f() { $args = func_get_args(); var_export($args); } f(10, "A", TRUE); ## 実行結果 array (0 => 10, 1 => 'A', 2 => true,) Python def f(*args, **kwargs): print repr(args) # タプル print repr(kwargs) # 辞書 f(10, "A", True, x=30, y=40) ## 実行結果 (10, 'A', True) {'y': 40, 'x': 30} 98
  • 99. 可変長引数:サンプル 普通の引数と可変長 引数とが混在可能 def img(src, **attrs): html = '<img src="%s" ' % src for k, v in attrs.iteritems(): html += ' %s="%s" ' % (k, v) html += ' />' return html Python print img('logo.gif', id='logo_gif', alt='logo image') #=> <img src="logo.gif" alt="logo image" id="logo_gif" /> 99
  • 100. 関数オブジェクト PHP ## 該当機能なし Python def f(a, b): return a+b; g=f # 関数を代入 print g(2, 3) #=> 5 print dir(g) # 属性を表示 print g.func_name #=> f • 「関数を定義する」=「関 数オブジェクトを作成し変 数に代入する」 • 関数もデータである 100
  • 101. 無名関数 PHP Python ## その場で関数を作成 $f = create_function( '$a, $b', 'return $a+$b;' ); echo $f(10, 20); #=> 30 var_export($f); #=> 'lambda_1' • 本体を文字列で指定 (< PHP5.3) ## その場で関数を作成 f = lambda a, b: a + b ## これは次とほぼ同じ ## def f(a, b): return a+b print f(10, 20) #=> 30 print f.func_name #=> '<lambda>' • 本体は式のみ(文は不可) 101
  • 102. 関数の再定義 PHP Python function f(x){ return x+x; } function f(x) { #=> Fatal Error return 2*x; } • 同名の関数を再定義できな い def f(x): return x+x def f(x): return 2*x • 関数の再定義は、「変数へ の再代入」でしかない 102
  • 103. 関数オブジェクト:サンプル PHP function sigma($x, $y, $f) { $sum = 0; for ($i=$x; $i<=$y; $i++) $sum += $f($i); return $sum; } function pow2($n) { return $n*$n; 文字列で指定 } sigma(1, 10, "pow2"); Python def sigma(x, y, f): sum = 0 for i in xrange(x, y+1): sum += f(i) return sum def pow2(n): return n*n 関数オブジェ クトを指定 sigma(1, 10, pow2) 103
  • 104. 変数のスコープ PHP Python list($x, $y, $z)=array(1,2,3); function f() { $x = 7; # local var global $y; $y = 9; # global var echo $z; # undefined var } f() echo "$x $y $zn"; #=>1 9 3 • 参照にも代入にも global宣言が必要 x, y, z = 1, 2, 3 # global def f(): x=7 # local var global y y=9 # global var print z # global var f() print x, y, z #=> 1 9 3 • 参照は何もしなくても可 • 代入はglobal宣言が必要 104
  • 105. 関数内関数 PHP Python function g($x, $y) { return ($x+$y)*($x-$y); } function f($a, $b, $c, $d) { return g($a, $b) + g($c, $d); } ## (2+3)*(2-3) + (4+5)*(4-5) print f(2, 3, 4, 5) • g() はグローバル (誰でもアクセス可) def f(a, b, c, d): def g(x, y): return (x+y)*(x-y) return g(a, b) + g(c, d) ## (2+3)*(2-3) + (4+5)*(4-5) print f(2, 3, 4, 5) • g() はローカル (f() の外からは見えない) 105
  • 106. 組み込み関数 Python len(seq) # 長さを求める repr(val) # val の文字列表現を返す range(start, end, step) # startからend-1までのリストを返す xrange(start, end, step) # range() のイテレータ版 sorted(seq) # ソートした新しいseqを返す sum(seq) # seqに含まれる数値を合計する vars(obj) # obj.__dict__ と同じ iter(obj) # obj.__iter__() と同じ 106
  • 107. 組み込み関数 (cont) Python id(obj) # オブジェクトIDを返す globals() # グローバル変数を表す辞書を返す locals() # ローカル変数を表す辞書を返す dir(obj) # 属性名の一覧 getattr(obj, name) # 属性値を取り出す setattr(obj, name, val) # 属性値を設定する delattr(obj, name) # 属性を削除する • 詳しい一覧は http://www.python.jp/doc/release/lib/built-in-funcs.html 107
  • 108. モジュール、パッケージ 【関連ドキュメント】 • チュートリアル: 6. モジュール http://www.python.jp/doc/release/tut/node8.html • 言語仕様リファレンス: 6.12 import 文 http://www.python.jp/doc/release/ref/import.html 108
  • 109. モジュールとは? ✤ ライブラリファイルのこと ✤ 実体はただのPythonスクリプト util.py PI = 3.14 def add(x, y): return x+y def sub(x, y): return x-y def _debug(s): return "*** "+repr(s); 109
  • 110. import main.py import util print util #=> <module 'util' from 'util.pyc'> print util.PI #=> 3.14 print util.add(10, 20) #=> 30 print util.sub(10, 20) #=> -10 print util._debug(123) #=> *** 123 • パッケージ名を接頭辞につけてアクセス する必要がある • 実際には、変数utilにモジュールオブ ジェクトが代入されるだけ 110
  • 111. from main.py 必要なものだけimport可能 from util import PI, add • PI = util.PI と同等 print PI #=> 3.14 • 変数 util は定義されない print add(10, 20) #=> 30 print sub(10, 20) #=> NameError: name 'sub' is not defind print util.sub(10, 20) #=> NameError: name 'util' is not defined すべてをimportする、 ただし '_' 始まりは除く from util import * print sub(10, 20) #=> -10 print _debug(123) #=> NameError: name '_debug' is not defined 111
  • 112. 注意 main.py import util # OK from util import add # OK import util.add # ImportError • from がないときは、import の引数はモ ジュール名でなくてはいけない (関数名 などは指定できない) 112
  • 113. __all__ util.py main.py __all__ = ('PI', 'add') PI = 3.14 def add(x, y): return x+y def sub(x, y): return x-y • 「import *」したときに 読み込まれる変数や関 数の名前を列挙する from util import * print PI print add(10, 20) print sub(10, 20) #=> NameError from util import sub print sub(10, 20) #=> -10 • __all__ に列挙されてな くても、明示的に importすることが可能 113
  • 114. as main.py 名前を変えてimport可能 import util as utility print utility.add(10, 20) from util import add as plus, sub as minus print plus(10, 20) try: import cStringIO as StringIO # C実装版があればそれを使う except ImportError: import StringIO # なければ pure Python 版を使う • StringIO = cStringIO と同等 114
  • 115. __name__ util.py 自分のパッケージ名を表す特殊変数 print __name__ #=> util (または main ) def add(x, y): return x+y コマンドラインでutil.pyが 指定されたときだけ実行 if __name__ == '__main__': assert add(10, 20) == 30 • 他からimportされたときは "util" に • そうでなければ "__main__" に 115
  • 116. 変数のスコープ foo.py main.py X = 10 # モジュールローカル def set_x(x) global X X=x • Pythonの「global」は モジュールローカル これは X = foo.X 相当 import foo from foo import X print X # モジュールローカル X = 20 print X, foo.X #=> 20 10 foo.X は変更されない foo.set_x(30) print X, foo.X #=> 20 30 X は変更されない 116
  • 117. __builtin__パッケージ python import __builtin__ ## 組み込みの関数や ## クラスの一覧 print dir(__builtin__) ## または for k in dir(__builtin__): v = getattr(__builtin__, k) print v • __builtin__は組み込み関数な どが入っているパッケージ python def h(s): s = s.replace('&', '&amp;') s = s.replace('<', '&lt;') s = s.replace('>', '&gt;') return s 可能だが非推奨!! __builtin__.h = h • PHPでいう「グローバル」 は、Pythonでは「組み込み」 (= __builtin__ に登録した) 117
  • 118. パッケージとは? ✤ 複数のモジュールを集め たディレクトリ ✤ ✤ __init__.py が必要 (中身は空でよい) ディレクトリは入れ子可能 mypkg/__init__.py ## 中身は空でよい mypkg/mod1.py def add(x, y): return x+y mypkg/mod2.py def sub(x, y): return x-y 118
  • 119. パッケージのimport main.py パッケージをimportすると mypkg/__init__ モジュールが importされる import mypkg print mypkg #=> <module 'mypkg' from 'mypkg/__init__.py'> print mypkg.mod1 #=> AttributeError: 'module' object has no attribute 'mod1' サブモジュールが自動的に importされるわけではない 119
  • 120. サブモジュールの import main.py サブモジュールは '.' で区切る import mypkg.mod1 親モジュールがインポートされる print mypkg #=> <module 'mypkg' from 'mypkg/__init__.pyc'> サブモジュールがインポートされる print mypkg.mod1 #=> <module 'mypkg.mod1' from 'mypkg/mod1.pyc'> print mod1 #=> NameError: name 'mod1' is not defined パッケージ名が必要 120
  • 121. サブモジュールの from import main.py from mypkg import mod1, mod2 print mod1 #=> <module 'mypkg.mod1' from 'mypkg/mod1.pyc'> パッケージ名なしでアクセス可能 (mod1 = mypkg.mod1 と同等) from mypkg import mod1 as m1, mod2 as m2 print m1 #=> <module 'mypkg.mod1' from 'mypkg/mod1.pyc'> 別名でimport可能 121
  • 122. サブモジュールの import * mypkg/__init__.py import mod1, mod2 __all__ = ('mod1', ) main.py from mypkg import * print mod1 #=> <module 'mypkg.mod1'> print mod2 #=> NameError import mypkg print mypkg.mod1 #=> <module 'mypkg.mod1'> print mypkg.mod2 #=> <module 'mypkg.mod1'> 122
  • 123. 標準添付モジュール ✤ sys … システムまわり ✤ os … OSやファイルシステム ✤ os.path … ファイルパス ✤ time … 時刻関連 ✤ re … 正規表現 ✤ __builtin__ … 組込の関数やクラスが定義されている 参考: ライブラリインデックス http://www.python.jp/doc/release/lib/lib.html 123
  • 124. その他 ✤ 検索パスはリスト sys.path に格納されている import sys sys.path.append("lib") # 末尾に追加 sys.path.insert(0, "lib") # 先頭に追加 ✤ 環境変数 $PYTHONPATH を設定すると、sys.path に追 加される 124
  • 125. オブジェクト指向 【関連ドキュメント】 • チュートリアル: 9. クラス http://www.python.jp/doc/release/tut/node11.html • 言語仕様リファレンス: 7.7 クラス定義 http://www.python.jp/doc/release/ref/class.html 125
  • 126. クラスとコンストラクタ PHP class User { var $name; function __construct($name) { $this->name = $name; } } • コンストラクタは __construct()  • インスタンスを表す疑似 変数は$this Python class User(object): def __init__(self, name): self.name = name • 親クラスとして object を 必ず指定すること! • コンストラクタは __init__()、第1引数は selfを指定すること! 126
  • 127. インスタンスオブジェクト PHP Python $u = new User("Haruhi"); echo $u->name; $u->name = "Suzumiya"; $u->age = 16; # OK var_export($u); • new演算子で生成 • 未定義のインスタンス変 数に代入可能 u = User("Haruhi") print u.name u.name = "Suzumiya" u.age = 16 # OK print u.__dict__ # or vars(u) • クラスを関数のように呼 び出して生成 • 未定義のインスタンス変 数に代入可能 127
  • 128. インスタンスメソッド PHP Python class User { var $name; function hello() { echo "Hello $this->name!"; } } $u = new User(); $u->name = "Haruhi"; $u->hello(); #=> Hello Haruhi! • 予約語 function で定義 class User(object): def hello(self): print "Hello %s!" % self.name u = User() u.name = "Haruhi" u.hello() #=> Hello Haruhi! • 予約語 def で定義 • 第1引数は必ずselfを指定 128
  • 129. 継承 PHP Python class Animal { function __construct($name) { $this->name = $name; } } class Dog extends Animal { function __construct($name) { parent::__construct($name); } } • 親クラスのコンストラク タを呼び出す (必要なら) class Animal(object): def __init__(self, name): self.name = name class Dog(Animal): def __init__(self, name): Animal.__init__(self, name) • 親クラスのコンストラク タを呼び出す (必要なら) 129
  • 130. super PHP Python class Dog extends Animal { function bark() { parent::bark(); } } class Dog(Animal): def bark(self): super(Dog, self).bark() # or Animal.bark(self) • 「parent::」で親クラス • 組み込み関数super()を のメソッドを呼び出す • クラス名を指定する必要 がない 使って呼び出す • クラス名を指定する必要 がある (←ダサい) 130
  • 131. 多重継承 PHP ## なし、 ## インターフェースで代用 Python class Animal(object): def bark(self): print "Bow wow" class Entity(object): def save(self): print "insert into ..." class Dog(Animal, Entity): pass 131
  • 132. isinstance PHP Python $u instanceof User isinstance(u, User) $u instanceof User || $u instanceof Animal isinstance(u, (User, Animal)) • instanceof は演算子 • isinstance() は組込関数 • タプルを使って複数のクラ スを指定可能 132
  • 133. アクセス制限 PHP Python public class User { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } • 'public'、'protected'、 } 'private' が利用可能 class User(object): def __init__(self, name): self._name = name self.__name = name u = User("Haruhi") print u.__dict__ #=> {'_name': 'Haruhi', # '_User__name': 'Haruhi'} • '_' で始まっていれば非public • 紳士協定であり強制力はない • '__' で始まるとクラス名が自動 付加 (Name Mangling) 133
  • 134. クラス変数、クラスメソッド PHP Python class User { static $table = "users"; function find($id) { $t = User::$table; echo "select from $t ..."; } } User::find(123); • 予約語「static」を使う • 「$this」にアクセスで きないメソッド class User(object): table = "users" @classmethod def find(cls, id): t = cls.table print "select from %s ..." % t User.find(123) • デコレータを使う (後述) • 第1引数はクラスオブ ジェクト 134
  • 135. インスタンスからクラスを参照 PHP Python class User { static $table = "users"; function m1() { echo static::$table; } } $user = new User(); $user->m1(); #=> users • 「static::」または 「self::」をつける class User(object): table = "users" def m1(self): print self.__class__.table user = User() user.m1() #=> users • クラスオブジェクトの属性と して参照 135
  • 136. スタティックメソッド Python class Foo(object): @staticmethod def hello(name='World'): print 'Hello %s!' % name Foo.hello("Mikuru") #=> Hello Mikuru! obj = Foo() obj.hello("Yuki") #=> Hello Yuki! • クラスからもインスタンスからも呼び出せる • インスタンス変数やクラス変数にはアクセス不可 136
  • 137. アクセッサ Python class User(object): u = User("Yuki") def __init__(self, name): print u.__dict__ self.__name = name #=> {'_User__name': 'Yuki'} def _getname(self): print u.name #=> Yuki return self.__name u.name = "Nagato" def _setname(self, name): #=> TypeError: msg = "'name' is read-only" 'name' is read-only raise TypeError(msg) name属性は読み取り name = property(_getname, _setname) 専用になっている • property() に getter と setter を指定する 137
  • 138. 型(type) Python type("foo") #=> <type 'str'> isinstance("foo", str) isinstance(u"f", unicode) isinstance([1, 2], list) isinstance({'a':1}, dict) #=> True #=> True #=> True #=> True isinstance(val, (tuple, list)) isisntance(val, (str, unicode)) # or isinstance(val, basestring) • list や str は、クラスに似た「型(type)」である • 「型」は組み込み関数 type() で取り出せる 138
  • 139. インスタンスとクラスの仕組み 【関連ドキュメント】 • チュートリアル: 9. クラス http://www.python.jp/doc/release/tut/node11.html • 言語仕様リファレンス: 7.7 クラス定義 http://www.python.jp/doc/release/ref/class.html 139
  • 140. オブジェクト指向言語の仕組み Function Class obj Variable Z: 123 Instance obj Class obj x: 10 y: 20 Z: 456 Method Tbl m1 m2 m3 Method Tbl m2 m3 m4 func (self) { ..... } func (self) { ..... } func (self) { ..... } 140
  • 141. インスタンスとクラスの関係 object クラス 辞書 f: <func> .__base__ g: <func> 変数 インスタンス クラス 辞書 z: 30 g: <func> .__dict__ 辞書 x: 10 .__class__ .__dict__ y: 20 141
  • 142. インスタンスとクラス変数 Python class User(object): name = "SOS" def hello(self): print self.name • インスタンスメソッドはクラス属性 インスタンスと結びついてない print User.name #=> SOS print User.hello #=> <unbound method User.hello> u = User() インスタンスと結びついている print u.name print u.hello #=> <bound method User.hello of ...> 142
  • 143. インスタンスとクラス変数 Python class User(object): name = "SOS" user = User() print user.name #=> SOS インスタンス変数が未設 定のときはクラス変数の 値が使われる user.name = "Haruhi" print user.name #=> Haruhi インスタンス変数はクラス 変数より優先される delattr(user, 'name') print user.name #=> SOS インスタンス変数を削除 すると元に戻る 143
  • 144. bound / unbound メソッド Python class User(object): def hello(self): print self.name u = User() u.name = "Kyon" u.hello() #=> Kyon User.hello(u) #=> Kyon f = u.hello; f() #=> Kyon • u.hello() と User.hello(u) は (ほぼ) 同等 • u.hello() は bound メソッド の呼び出し • User.hello() は unbound メ ソッドの呼び出し、第1引数 に self が必要 • bound メソッドは変数に代入 して呼び出すことが可能 144
  • 145. 関数とインスタンスメソッド Python これは普通の関数 def hello(self): print self.name print hello #=> <function hello> 普通の関数をクラス属性に代入するだけ class User(object): で、インスタンスメソッドとして利用可能 pass User.hello = hello print User.hello #=> <unbound method User.hello> u = User() print u.hello #=> <bound method User.hello> 145
  • 146. インスタンスごとのメソッド Python def hello(self): print self.name class User(object): pass import types u = User(); u.name = "Mikuru" u.hello = types.MethodType(hello, u) print u.hello #=> <bound method> u.hello() #=> Mikuru • そのインスタンスだけのメソッドを設定する には、 bound method を設定するだけでよい • types.MethodType でラップすると bound method を生成できる 146
  • 147. __slots__ Python class User(object): __slots__ = ('name', 'age') def hello(self): print "Hello %s!" % self.name u = User() u.name = "Haruhi" u.hello() # Hello Haruhi! u.phone = "090-..." # AttributeError print u.__dict__ # AttributeError • __slots__ に指定した属 性のみ利用可能、それ 以外はAttributeError • デフォルト値としての クラス属性は参照され なくなる • インスタンスはdict ベースではなく構造体 ベースになる • 子クラスには引き継が れない 147
  • 148. ファイル操作 【関連ドキュメント】 • チュートリアル: 7.2 ファイルを読み書きする http://www.python.jp/doc/release/tut/node9.html#SECTION009200000000000000000 • ライブラリリファレンス: 3.9 ファイルオブジェクト http://www.python.jp/doc/release/lib/bltin-file-objects.html 148
  • 149. ファイルを読み込む PHP Python $f = fopen("a.txt", "r"); echo fread($f, filesize("a.txt")); fclose($f); f = open("a.txt") print f.read() f.close() echo file_get_contents("a.txt"); print open("a.txt").read() CPythonのGCはリファレンス カウント方式なので、参照さ れなくなったファイルオブジェ クトは自動的にcloseされる with open("a.txt") as f: print f.read() with文を使うとより安全 149
  • 150. ファイルに書き込む PHP Python $f = fopen("file.txt", "w"); fwrite($f, "ABC"); fclose($f); f = open("file.txt", "w") f.write("ABCn") f.close() file_puts_contents("file.txt", "ABC"); open("file.txt", "w").write( "ABC") with open("file.txt", "w") as f: f.write("ABC") with文を使うとより安全 150
  • 151. 文字コードを指定して読み書き Python import codecs f = codecs.open("file.txt", encoding="utf8") x = f.read() # strではなくunicodeを返す print type(x) #=> <type 'unicode'> s = x.encode('utf8') # unicodeをstrへ変換 f.close() 151
  • 152. 1行ずつ読み込む PHP $f = fopen("file.txt", "r"); $line = fgets($f); while ($line !== FALSE) { var_export($line); $line = fgets($f); } fclose($f); Python for line in open("file.txt"): print repr(line) ## または with open("file.txt") as f: for line in f: print repr(line) 152
  • 153. ファイルが存在するかどうか PHP file_exists("file_or_dir"); is_file("file.txt"); is_dir("/tmp"); Python import os os.path.exists("file_or_dir") os.path.isfile("file.txt") os.path.isdir("/tmp") 153
  • 154. ファイル操作 PHP rename("old", "new") unlink("file") mkdir("dir") rmdir("dir") Python import os os.rename("old", "new") os.unlink("file") os.mkdir("dir") os.rmdir("dir") 154
  • 155. ファイル名操作 PHP Python $s = "path/to/file"; basename($s); dirname($s); import os s = 'path/to/file' os.path.basename(s) os.path.dirname(s) glob('*.txt'); import glob glob.glob('*.txt') 155
  • 156. 例外処理 156
  • 157. 基本構文 Python try: raise Exception("message") except TypeError, ex: print ex except (KeyError, NameError), ex: print ex finally: タプルを使って複数のエ pass ラークラス名を指定可能 157
  • 158. raise Python raise NameError('Haruhi: no such student.') # 例外オブジェクト raise NameError, 'Haruhi: no such student.' # クラスと引数 raise # 例外を再送 try: import sos except ImportError: logging.info('sos: module not found.') raise # 例外をログに記録してから再送 158
  • 159. else節 Python try: f = open('file.txt') except Exception, ex: print str(ex) else: • 例外が発生しなかったとき print f.read() だけ else 節が実行される finally: if f: f.close() 159
  • 160. 例外オブジェクト Python try: raise Exception('mesg', 123, True) except Exception, ex: print ex.message print ex.args #=> ('mesg', 123, True) arg1, arg2, arg3 = ex # 多重代入が可能 print [arg1, arg2, arg3] #=> ['mesg', 123, True] 160
  • 161. 例外クラス Python class HttpError(Exception): pass • Exceptionクラスを継承する class Http404NotFound(HttpError): • 種類ごとに基底クラスを定 義するとよい status = '404 Not Found' def __init__(self, url): • __str__()を適切にオーバー self.url = url ライドするとよい self.message = 'Page Not Found' (str(ex) でメッセージが表示 def __str__(self): されるようになる) return self.message 161
  • 162. 主な例外クラス (1) Python # SynstaxError … 文法が間違っている、またはコードに日本語が # 含まれているのにマジックコメントがない True && True #=> SyntaxError: invalid syntax # TypeError … データや引数の型または数が間違っている list1 = ['Haruhi','Mikuru','Yuki'] list1["3"] #=> TypeError: list indices must be integers list1.append('Kyon', 'Itsuki') #=> TypeError: append() takes exactly # one argument (2 given) 162
  • 163. 主な例外クラス (2) Python # ValueError … 型は正しいが値として間違っている f = open('members.txt') f.close() f.read() #=> ValueError: I/O operation on closed file # UnicodeEncodeError … ユニコード関連のエラー print u'ハルヒ'.encode('utf-8') print u'ハルヒ' #=> UnicodeEncodeError: 'ascii' codec can't # encode characters in position 0-2: ordinal # not in range(128) 163
  • 164. 主な例外クラス (3) Python # NameError … 変数や関数が存在しない x = haruhi #=> NameError: name 'haruhi' is not defined # AttributeError … 属性やメソッドが存在しない、 # または変数がNoneである class Kyon(object): pass Kyon().megane #=> AttributeError: 'Kyon' object has # no attribute 'megane' None.megane #=> AttributeError: 'NoneType' object has # no attribute 'megane' 164
  • 165. 主な例外クラス (4) Python # KeyError … 辞書のキーが存在しない {'a':1}['b'] #=> KeyError: 'b' # IndexError … リストやタプルで添字が範囲外 list1 = ['Haruhi','Mikuru','Yuki'] list1[3] #=> IndexError: list index out of range # IOError … ファイルが存在しない、アクセス権限がない、等 open('haruhi.txt') #=> IOError: [Errno 2] No such file # or directory: 'haruhi.txt' 165
  • 166. 主な例外クラス (5) Python # ImportError … 存在しないモジュールをimportしようとしている import sos #=> ImportError: No module named sos 166
  • 167. 組み込み例外クラスの一覧 Python ## 組み込みの例外クラスをすべて表示する for name, val in vars(__builtins__).iteritems(): if isinstance(val, type) and issubclass(val, Exception): print name # 名前だけ表示 print "%s: %s" % (name, val.__doc__) # ドキュメントも表示 167
  • 168. 正規表現 【関連ドキュメント】 • ライブラリリファレンス: re - 正規表現 http://www.python.jp/doc/release/lib/module-re.html • チュートリアル: 10.5 文字列のパターンマッチング http://www.python.jp/doc/release/tut/node12.html#SECTION0012500000000000000000 168
  • 169. パターンマッチ PHP $s = '<img src="logo.gif">'; if (preg_match('/src="(.*?)"/', $s, $m)) echo $m[0], " ", $m[1]; #=> src="logo.gif" logo.gif Python import re • re.match()は先頭にマッチ s = '<img src="logo.gif">' • re.search()は途中にもマッチ m = re.search(r'src="(.*?)"', s) if m: print m.group(0), m.group(1) #=> src="logo.gif" logo.gif 169
  • 170. オプション指定 PHP $s = '<h1>Title</h1>'; if (preg_match('/^<h1>(.*?)</h1>$/msi', $s, $m)) echo $m[1]; Python import re s = '<h1>Title</h1>' m = re.search(r'^<h1>(.*?)</h1>$', s, re.M|re.S|re.I) if m: m.group(1) • re.search()の第3引数にオプション指定 170
  • 171. 置換 PHP $s = '<img src="logo.gif">'; echo preg_replace('/(w+.gif)/', 'img/1', $s); #=> <img src="img/logo.gif"> Python import re s = '<img src="logo.gif">' print re.sub(r'(w+.gif)', r'img/1', s) #=> <img src="img/logo.gif"> • re.sub() の第4引数に 置換回数を指定できる (例: 1 なら最初の1回だ け置換) 171
  • 172. コールバックつき置換 PHP $ESC = array('<'=>'&lt;', '>'=>'&gt;', '&'=>'&amp;'); function f($m) { global $ESC; return $ESC[$m[0]]; } echo preg_replace_callback('/[<>&]/', 'f', '<A&B>'); Python import re ESC = {'<':'&lt;', '>':'&gt;', '&':'&amp;'} f = lambda m: ESC[m.group(0)] print re.sub(r'[<>&]', f, '<A&B>') #=> &lt;A&amp;B&gt; • コールバック関数の実 行結果で置換される 172
  • 173. 繰り返しマッチ PHP $s = file_get_contents("index.html"); preg_match_all('/href="(.*?)"/', $s, $arr); foreach ($arr[0] as $url) echo $url, "n"; Python import re s = open("index.html").read() for m in re.finditer(r'href="(.*?)"', s): print m.group(1) • re.findall()はリストを返す • re.finditer()はイテレータ (後述)を返す 173
  • 174. 分割 PHP $s = '/public/img/logo.gif'; $arr = preg_split('///', $s); var_export($arr); #=> array(0=>'', 1=>'public', 2=>'img', 3=>'logo.gif') Python • re.split()の第3引数に最大分 import re 割数を指定できる s = '/public/img/logo.gif' list1 = re.split(r'/', s) print list1 #=> ['', 'public', 'img', 'logo.gif'] 174
  • 175. コンパイル PHP ## 該当機能なし Python import re s = '<h1>Title</h1>' pattern = re.compile(r'^<h1>(.*?)</h1>$', re.M|re.S|re.I) m = pattern.search(s) • 正規表現を事前にコンパイル可能 if m: m.group(1) • 実行効率は多少よくなる 175
  • 176. メソッド一覧 reパッケージ re.match(rexp, str) re.search(rexp, str) re.sub(rexp, repl, str, n=0) re.subn(rexp, repl, str, n=0) re.split(rexp, str, n=0) re.findall(rexp, str) re.finditer(rexp, str) re.compile(rexp, repl, str) re.purge(rexp, repl, str) re.escape(rexp, repl, str) patternオブジェクト pattern.match(str) pattern.search(str) pattern.sub(repl, str, n=0) pattern.subn(repl, str, n=0) pattern.split(str, n=0) pattern.findall(str) pattern.finditer(str) pattern = re.compile(rexp) - 176
  • 177. 高階関数、クロージャ 【関連ドキュメント】 • チュートリアル: 4.6 関数を定義する http://www.python.jp/doc/release/tut/node6.html#SECTION006600000000000000000 • 言語仕様リファレンス: 4.1 名前づけと束縛 (naming and binding) http://www.python.jp/doc/release/ref/naming.html • 言語仕様リファレンス: 7.6 関数定義 http://www.python.jp/doc/release/ref/function.html 177
  • 178. 高階関数とは? ✤ 関数をデータとして扱う関数 ✤ 関数を引数とする関数 ✤ 関数を戻り値とする関数 Python def f(n): return n*n # 関数の定義 f = lambda n: n*n # 関数の作成 • 「関数を定義する」=「関数オブジェクトを作成 (して変数に代入) する」 • 関数オブジェクトをデータとして扱える 178
  • 179. よくある光景 Python def map_square(items): L = [] for x in items: L.append(x * x) return L def map_label(items): L = [] for x in items: L.append("(%s)" % x) return L nums = [1, 2, 3] print map_square(nums) #=> [1, 4, 9] nums = [1, 2, 3] print map_label(nums) #=> ['(1)', '(2)', '(3)'] • 一部の処理が違うだけで、あとは一緒の関数 179
  • 180. 関数を引数にとる関数: map Python def map(func, items): L = [] for x in items: L.append(func(x)) return L nums = [1, 2, 3] f = lambda n: n*n print map(f, nums) f = lambda n: '(%s)' % n print map(f, nums) • 違う処理を関数で与える • map() は組み込み関数と して提供済 180
  • 181. 関数を引数にとる関数: filter Python def filter(func, items): L = [] for n in items: if func(n): L.append(n) return L • 条件を満たす要素だけを nums = [1, 7, 3, 2, 0, 5, 0, 8] print filter(lambda n: n % 2, nums) #=> [1, 7, 3, 5] print filter(lambda n: n > 5, nums) #=> [7, 8] 集める関数 • filter() は組み込み関数と して提供済 181
  • 182. 関数を引数にとる関数: max Python def max_by(func, items): is_first = True for x in items: v = func(x) if is_first: max, item = v, x ! is_first = False elif max < v: max, item = v, x return item SOS = [('Haruhi', 'C'), ('Mikuru', 'E'), ('Yuki', 'A'), ] f = lambda x: x[1] print max_by(f, SOS) #=> ('Mikuru', 'E') • 評価関数が最大になる要素を返す • 組み込み関数 max(items, key=func) が提供済 182
  • 183. 関数を引数にとる関数: reduce Python def reduce(func, items, init): accum = init for x in items: accum = func(accum, x) return accum nums = xrange(1, 10+1) func = lambda a, x: a+x print reduce(func, nums, 0) #=> 55 • 累積値 (accum) と要素 (x) を使って 何らかの処理を行う関数 • 組み込み関数として提供済 183
  • 184. 関数を返す関数 普通に定義した関数 と同様に利用可能 Python odd, even = "#FCC", "#CCF" f = oddeven() def oddeven(): print f(1) #=> #FCC def func(n): print f(2) #=> #CCF if n % 2 == 1: print f(3) #=> #FCC return odd else: • 「関数を定義する」=「関数オブジェ return even クトを作成 (して変数に代入) する」 return func 関数内部で作成 した関数を返す 184
  • 185. 外側のローカル変数を参照 Python def oddeven(odd, even): def func(n): if n % 2 == 1: return odd else: return even return func • グローバル変数を使わない ので、挙動の異なる関数を 多数作成できる f1 = oddeven("red", "blue") print f1(1) #=> red print f1(2) #=> blue print f1(3) #=> red f2 = oddeven("#FCC", "#CCF") print f2(1) #=> #FCC print f2(2) #=> #CCF print f2(3) #=> #FCC 185
  • 186. クロージャ ✤ 関数+外側のローカル変数 ✤ 内側の関数オブジェクトが生存する間は、それが参照している、 外側のローカル変数も生存する(すぐには消えない)。 Python def oddeven(odd, even): def func(n): if n % 2 == 1: return odd else: return even return func f1 = oddeven('#FCC', '#CCF') print f1(1), f1(2), f1(3) f2 = oddeven('red, 'blue') print f2(1), f2(2), f2(3) • 内側の関数が存命中なので、 変数oddとevenも存命中 186
  • 187. クロージャではない例 Python def oddeven(odd, even): def func(n): if n % 2 == 1: return '#FCC' else: return '#CCF' return func odd, even = '#FCC', '#CCF' def oddeven(): def func(n): if n % 2 == 1: return odd else: return even return func • どちらも、外側のローカル変数を参照 していないので、クロージャではない 187
  • 188. 変数スコープ Python def outer(): a=b=c=0 d = [] def inner(): print a b=1 nonlocal c c=1 d[0] = 1 return inner # グローバル変数 # outer()のローカル変数 # 同上 # 同上 # 同上 # inner()のローカル変数 # Python 3.0以降で利用可能 # outer()のローカル変数(Python 3.0以降) # outer()のローカル変数 # 同上 188
  • 189. 引数の部分適用 ✤ N個の引数を持つ関数にM個の引数を与えることで、 (N-M)個の引数を持つ関数を新たに作成すること Python def map_square(items): func = lambda x: x*x return map(func, items) ## 変形 func = lambda x: x*x def _map(items): return map(func, items) map_square = _map 部分適用を 行う関数 ## さらに変形 def map_builder(func): def _map(items): return map(func, items) return _map map_square = map_builder(lambda x: x*x) map_increase = map_builder(lambda x: x+1) 189
  • 190. デコレータ 【関連ドキュメント】 • 言語仕様リファレンス: 7.6 関数定義 http://www.python.jp/doc/2.5/ref/function.html 190
  • 191. デコレータ ✤ 関数を修飾するための機能 ✤ 実体は、関数を受け取り関数を返すような関数 Python class Foo(object): @classmethod def hello(cls): print "Hello World!" ## これは次と同じ hello = classmethod(hello) 引数指定も可能 class Foo(object): @foo(123, "bar") def hello(cls): print "Hello World!" ## これは次と同じ func = foo(123, "bar") hello = func(hello) 191
  • 192. サンプル: TemplateMethod(1) Python デコレータは、関数を受け取 り、関数を返すような関数 def with_dummy(func): def newfunc(self): open('A.txt', 'w') .write('AAA') # setup try: func(self) # do test finally: os.unlink('A.txt') # teardown return newfunc ## 使用例 @with_dummy def test_1(self): # ... A.txt を使ったテスト... @with_dummy def test_2(self): # ... A.txt を使ったテスト... もとの関数を呼び出すような 新しい関数を生成して返す 192
  • 193. サンプル: TemplateMethod(2) Python デコレータを生成する関数 def with_dummy(fname, data): def deco(func): def newfunc(self): open(fname, 'w') ! .write(data) try: func(self) finally: os.unlink(fname) return newfunc return deco ## 使用例 @with_dummy('x.txt', 'XXX') def test_1(self): # ... y.txt を使ったテスト... @with_dummy('y.txt', 'YYY') def test_2(self): # ... y.txt を使ったテスト... 生成したデコレータを返す 193
  • 194. サンプル: メモ化デコレータ(1) Python デコレータは、関数を1つ受け取り、 かつ関数を返すような関数 def memoize(f): memo = {} def g(n): if n not in memo: memo[n] = f(n) return memo[n] return g f()の計算結果を保 存し、再利用する ## 使用例 @memoize def fib(n): if n <= 2: return 1 else: return fib(n-1)+fib(n-2) print fib(50) # 爆速! 194
  • 195. サンプル: メモ化デコレータ(2) 引数が複数個ある 関数にも適用可能 ## 任意個の引数をとれるよう拡張 ## 使用例 Python def memoize(f): @memoize 任意個の引数を memo = {} def tak(x, y, z): 受け取り、… def g(*args): if x <= y: return y if args not in memo: else: memo[args] = f(*args) return tak(tak(x-1, y, z), return memo[args] tak(y-1, z, x), それらをまる return g tak(z-1, x, y)) ごとf()に渡す argsはタプルなので辞書 のキーとして利用可能 print tak(13, 5, 0) #=>13 195
  • 196. サンプル:任意の引数へ対応 Python ## 任意の関数の戻り値を ## 2倍するデコレータ def cheat(f): def g(*args, **kwargs): v = f(*args, **kwargs) return 2*v return g ## 使用例 @cheat def add(x,y): return x+y print add(3, y=5) #=> 16 受け取ったすべての引数を、 キーワード引数も含めて別の 関数にそのまま渡す 引数のどんな渡 し方でも大丈夫 196
  • 197. サンプル:デコレータ生成関数 Python デコレータを生成する関数 デコレータ def cheat(n): def _cheat(f): def g(*args, **kwargs): v = f(*args, **kwargs) return n * v return g return _cheat ## 使用例 @cheat(3) def add(x,y): return x+y print add(3, 5) #=> 24 デコレータを返す 197
  • 198. イテレータ 【関連ドキュメント】 • チュートリアル: 9.8 イテレータ (iterator) http://www.python.jp/doc/release/tut/node11.html#SECTION0011800000000000000000 • ライブラリリファレンス: 3.5 イテレータ型 http://www.python.jp/doc/release/lib/typeiter.html 198
  • 199. イテレータとは? ✤ 「繰り返し」という概念を抽象化 ✤ 「次の値を取得する」と「次の値がなければ終了する」 ✤ 違うデータ構造に対し同一の方法で繰り返しが可能になる Python イテレータを生成 list1 = [10, 20, 30] it = list1.__iter__() print it.next() #=> 10 print it.next() #=> 20 終了時に例外を発生 print it.next() #=> 30 print it.next() #=> StopIteration next()で次の値を取得 199
  • 200. イテレータとfor文 Python for item in [10, 20, 30]: print item • for文は内部でイテレータを 生成し実行している ## これは次と (だいたい) 同じ it = [10, 20, 30].__iter__() try: while True: item = it.next() print item except StopIteration: pass 200
  • 201. イテレータとfor文 (cont) Python for line in open('file.txt'): print line, ## これは次と (だいたい) 同じ it = open('file.txt').__iter__() try: while True: line = it.next() print line, except StopIteration: pass 201
  • 202. サンプル: ListItems Python class ListItems(object): def __init__(self, list1): self.list = list1 self.i = -1 def __iter__(self): return self def next(self): self.i += 1 if self.i >= len(self.list): raise StopIteration() item = self.list[self.i] return "<li>%s</li>" % item ## 使用例 list1 = ['foo', 'bar', 'baz'] for s in ListItems(list1): print s ## 実行結果 <li>foo</li> <li>bar</li> <li>baz</li> 202
  • 203. ジェネレータ 【関連ドキュメント】 • チュートリアル: 9.9 ジェネレータ (generator) http://www.python.jp/doc/release/tut/node11.html#SECTION0011900000000000000000 • 言語仕様リファレンス: 6.8 yield 文 http://www.python.jp/doc/release/ref/yield.html 203
  • 204. 通常の関数 Python ## 通常の関数 def f1(): x = 10 return x x += 1 return x x += 1 return x print f1() print f1() print f1() print f1() #=> 10 #=> 10 #=> 10 #=> 10 • 呼び出すごとに最初から 実行される • ローカル変数の値は保存 されない 204
  • 205. ジェネレータ Python ## ジェネレータ関数 ## ジェネレータオブジェクトを生成 def ex1_gen(): g = ex1_gen() x = 10 print g.next() #=> 10 yield x print g.next() #=> 11 x += 1 print g.next() #=> 12 yield x print g.next() #=> StopIteration x += 1 yield x • 再開可能な関数 (resumable function) • yield で実行を一次中断し、.next() で 再開(RPGのセーブと類似) • 最後に例外StopIterationが発生 205
  • 206. サンプル:フィボナッチ数列 Python ジェネレータ関数 def fib(): x, y = 1, 1 while True: yield x x, y = y, x+y 再帰を使わないので爆速 ジェネレータオブジェクト g = fib() print g.next() print g.next() print g.next() print g.next() print g.next() print g.next() print g.next() print g.next() #=> 1 #=> 1 #=> 2 #=> 3 #=> 5 #=> 8 #=> 13 #=> 21 206
  • 207. サンプル:cycle() Python ジェネレータ関数 def cycle(*args): i=0 n = len(args) while True: yield args[i] i += 1 if i == n: i=0 ジェネレータオブジェクト g = cycle("odd", "even") print g.next() #=> odd print g.next() #=> even print g.next() #=> odd f = cycle("odd", "even").next print f() #=> odd print f() #=> even print f() #=> odd 207
  • 208. ジェネレータとイテレータ Python g = ex1_gen() print repr(g) #=> <generator at 0x13c0200> print repr(g.__iter__()) #=> <generator at 0x13c0200> • .__iter__() は自分自身を返す • .__iter__() と .next() があるので for 文で使える for val in ex1_gen(): print val ## 次とほぼ同じ g = ex1_gen().__iter__() try: while True: print g.next() except StopIteration: pass 208
  • 209. 利点:長いリストを作らずに済む Python range(1, 5) #=> [1,2,3,4] xrange(1,5) #=> xrange for i in range(1, 1000001): print i for i in xrange(1, 1000001): print i • range()は長いリストを生成する (=メモリを大量に消費) • xrange()はxrangeオブジェクト をひとつ作成するだけ(=メモ リ消費量が少ない) 209
  • 210. 利点:「無限」を扱える Python ## .next() が呼び出される ## 限りフィボナッチ数列 ## を無限に計算し続ける def fib_gen(): x, y = 0, 1 while True: x, y = y, x+y yield x ## フィボナッチ数列を ## 無限に出力し続ける g = fib_gen() while True: print g.next() 210
  • 211. 利点: '処理' と '条件' を分離 Python ## 1000個までのfib数列 x, y = 0, 1 i=0 while i < 1000: i += 1 x, y = y, x+y print x ## 1000 未満までのfib数列 x, y = 0, 1 x, y = y, x+y while x < 1000: print x x, y = y, x+y • generatorなしだと、「計算」や「処理」 と、ループの終了判定とが混在 =終了条件が異なれば、「計算」や「処 理」をもう一度書かなければいけない 211
  • 212. 利点: '処理' と '条件' を分離 Python ## .next() が呼び出される ## 限りフィボナッチ数列 ## を無限に計算し続ける def fib_gen(): x, y = 0, 1 while True: x, y = y, x+y yield x ## 1000個 g = fib_gen() i=0 while i < 1000: i += 1 n = g.next() print n ## 1000 未満 g = fib_gen() n = g.next() while n < 1000: print n n = g.next() • 「無限」が扱える =終了条件を指定しなくてよい (別途指定できる) =ループの「処理」と「終了条件」とを分離できる 212
  • 213. ジェネレータ式 Python g = ( (i, i*i) for i in xrange(1, 5) ) print g #=> <generator object> print g.next() #=> (1, 1) print g.next() #=> (2, 4) print g.next() #=> (3, 9) print g.next() #=> (4, 16) print g.next() #=> StopIteration • 丸カッコの中に内包表記 (list complehension) を書くと、それだけでジェネレータになる 213
  • 214. ジェネレータ式 (cont) Python names = ['Haruhi', 'Mikuru', 'Yuki'] tuples = [ (s, len(s)) for s in names ] print tuples #=> [('Haruhi', 6), ('Mikuru', 6), ('Yuki', 4)] d1 = dict(tuples) print d1 #=> {'Haruhi': 6, 'Mikuru': 6, 'Yuki': 4 } d2 = dict( (s, len(s)) for s in names ) print d2 #=> {'Haruhi': 6, 'Mikuru': 6, 'Yuki': 4 } • 引数のカッコの中にジェネレータ式が書ける • リストを引数にとる関数は、ジェネレータも 受け付けることが多い 214
  • 215. .next()と.send() ## ジェネレータ ## メインプログラム yield 123 val = g. next() # val == 123 yield 456 val = g.next() # val == 456 StopIteration val = g.next() # StopIteration • ジェネレータからメインへは値を渡せる (yield の引数) • その逆は? 215
  • 216. .next()と.send() (cont) ## ジェネレータ ret = yield 123 # ret == 'aaa' ret = yield 456 # ret == 'bbb' StopIteration ## メインプログラム val = g. next() # or .send(None) # val == 123 val = g.send('aaa') # val == 456 val = g.send('bbb') # StopIteration • .send() を使う (.send()の引数がyieldの戻り値) • .send(None) は .next() と同じ 216
  • 217. ジェネレータ: サンプル Python • yield で値 (=質問文) を返しながら、同時 に別の値 (=ユーザ回答) を受け取っている # -*- coding: utf-8 -*def yome_gen(): ans = yield '(a)元気な子 (b)おとなしい子' if ans == 'a': ans = yield '(a)ツンデレ (b)笑い上戸' yome = ans == 'a' and 'ハルヒ' or '鶴屋さん' elif ans == 'b': ans = yield '(a)巨乳 (b)貧乳' yome = ans == 'a' and 'みくる' or '長門' raise StopIteration(yome) 217
  • 218. ジェネレータ: サンプル (cont) Python g.send(None) は g.next() と同じ g = yome_gen() • send() で値 (=ユーザ回答) を渡しながら、 ans = None かつ戻り値 (=質問文) を受け取っている try: while True: question = g.send(ans) ## 実行例 print question, ' >>', (a)元気な子 (b)おとなしい子 >> a ans = raw_input() (a)ツンデレ (b)笑い上戸 >> b except StopIteration, ex: yome = ex.args[0] おすすめは 鶴屋さん print 'おすすめは', yome 218

×