ちょこっと Python NDS #36 @civic
ちょこっとPythonNDS #36 @civic
@civic
• NDS 代表
• Python勉強中
• Java, Python, JavaScript
• Fix HootSuite, SeatNext
このプレゼンの目的
• ユーザが少しでも増えればいいかなぁって思って
• 詳細→公式ドキュメントがたっぷりあります
• 面白いところ、特徴的なところ
• 始めるための環境設定について
Pythonについて
Pythonについて
• 主要プラットフォームでのサポート
• 初心者から上級者まで幅広く
• Python2系から3系に移行
• 2.7.6
• 3.3.4
The Zen of Python美は醜より良い 明示は暗黙より良い 単純は複雑より良い 複雑なほうが理解しにくいよりは良い 平坦は入れ子より良い 疎は密より良い 読みやすさが重要 「特殊なケース」はルールを破るほど特殊ではない しかし、実利は純粋さより重要 エラーを黙って通してはいけない ただし、明示的に黙らせた場合は別 曖昧さに面したら、正解を推測したくなる誘惑を退けよ 一つの明確なやり方があるべきだ。そしてただ一つであることが望ましい。 しかし、その方法はオランダ人以外にはとっつきにくいかもね
もし実装方法を説明するのが難しければ、それは悪いアイデアだ もし実装方法を説明するのが易しければ、それは良いアイデアかもしれない 名前空間は超すごいアイデアだ、もっとすごいことをやろうぜ!
禅 of Python: 20の格言: http://goo.gl/EbuWMi
公式ドキュメント
公式ドキュメント
公式ドキュメント
• 日本語公式ドキュメントが充実
• http://docs.python.jp/2/
• http://docs.python.jp/3.3/
• 充実したチュートリアル
• 日本語翻訳プロジェクト epub, pdf, htmlの配布
標準ライブラリ
標準ライブラリ
• バッテリ同梱 (batteries included)という哲学
• チュートリアルの標準ライブラリミニツアー
標準ライブラリミニツアー
環境構築
環境構築
• パッケージ管理
• Pythonバージョンの管理
• virtualenv
パッケージ管理
• ライブラリパッケージのリポジトリPyPI (Python Package Index)で統一
• PyPIを利用するツール pip, easy_install
• PyPIに置くディストリビューションを作成する仕組みは多数ある(distutils, setuptool, Distribute, distutils2, packaging)
とりあえずpip$ pip search Jinja2 $ pip install Jinja2 $ pip uninstall Jinja2 !$ pip freeze > requirements.txt # インストールしたパッケージを書き込み !$ cat requirements.txt Jinja2==2.7.2 MarkupSafe==0.19 argparse==1.2.1 wsgiref==0.1.2 !$ pip install -r requirements.txt # requirements.txtからインストール
Pythonバージョンの管理
• pyenv, pythonzなど
• システムPythonを使わずユーザ権限でインストール
• virtualenvを使えば不要?
• 細かいバージョン指定
• ビルドオプションの指定
virtualenv
• プロジェクトごとにPython環境を構築
• python実行ファイル
• site-packages
• これを使うためにpyenv系はあまり要らない
virtual環境の作成
$ virtualenv —python=/path/to/python venv
• —pythonでpython実行ファイルのパスを指定
• pyenvがほぼ不要に
virtualenv アクティブ・非アクティブ
$ source venv/bin/activate $ deactivate
PATHの先頭にvenv/binが入る
virtualenv環境下でのpip
$ tree -d -L 3 venv/ venv/ ├── bin ├── include │ └── python2.7 ->リンク └── lib └── python2.7 ├── config ->リンク ├── distutils ├── encodings ->リンク ├── lib-dynload ->リンク └── site-packages
環境まとめ
• プロジェクトごとにvirtualenvで仮想python環境
• pipでインストールできるようにrequirements.txtを用意
• pyenvなどは必須ではない
言語の特徴
インデント
def say(msg): if msg == "Hello": print "Hello World" else: print msg
インデントブロックの弊害def say(msg): foo = 1 !
if msg == "Hello": print "Hello World" else: # print msg
ブロックが空行になるとNG →pass
インデントブロックの弊害def say(msg): foo = 1 !
# if msg == "Hello": # print "Hello World" # else: print msg
ifの条件式をコメントアウトして、 かならずelseを通るように…
文字列'single quote' "double quote" # 同一 !
""" multiline string string""" !
r"raw string \n" #非エスケープ u"unicode string"
• Python2, 3の文字列の違い • “”は、2ではascii文字列。3ではunicode文字列( u””と同等)
シーケンス型
a = ['spam', 'eggs', 'hello', 'world'] a[0] # -> spam a[-1] # -> world a[1:3] # -> ['eggs', 'hello'] a[:2] # -> ['spam', 'eggs'] !
"Hello"[0:3] # -> "Hel" 文字列
リスト、文字列、タプルなどスライスの例:
辞書型
a = {'a': 10, 'b': 20, 100: 'hundred'} # keyは文字列とは限らない !
a['a'] # -> 10
リスト内包表記
a = [10, 20, 30] !
b = [x * 2 for x in a] # [20, 40, 60] !
c = [x * 3 for x in a if x > 10] #[60, 90]
リストを作り出すための簡潔な表記法
map関数に近い
関数オブジェクト• 関数も普通のオブジェクト
• 他のオブジェクトと同じようにリストにいれたり、引数にしたりできるdef func1(): pass !
print func1 # -> <function myfunc at ...>
関数オブジェクト• def文は式ではない
• 無名関数を生成して代入できない
• lambda式なら書けるがこんどは文が書けない
// javascript !
func2 = function(x){ x + 1};
LEGBスコープ
• L: Local (関数内)
• E: Enclosing function (外側の関数)
• G: Global (モジュール内)
• B: Built-in (プログラム全体)
LEGBスコープa = 1 def outer_func(): a = 2 def inner_func(): a = 3
• すべて違うスコープ
• ちなみにブロックでスコープは生成されない
変数宣言などない
• 代入=宣言
a = 1 def func(): a = 2 !print a # -> 1 func() print a # -> 1
外側の変数に代入している つもり?
なぜか?
• Pythonでは変数宣言がない
• 代入=変数宣言
• 関数の外側の変数に代入したくてもローカルスコープの変数宣言になってしまうため
a = 1 def func(): a = 2
対処法(L→G)
• ローカルスコープからグローバルスコープの変数を書き換える場合
a = 1 def func(): global a a = 2
グローバルの変数使うよ宣言
対処法(L→E)Python3
• ローカルスコープからエンクロージングスコープの変数を書き換える場合(Python3)
a = 1 # ...(A) def outer_func(): a = 2 def inner_scope(): nonlocal a a = 3 外部の変数使うよ宣言
対処法(L→E) Python2
• ローカルスコープからエンクロージングスコープの変数を書き換える場合(Python2)
a = 1 # ...(A) def outer_func(): a = [2] def inner_scope(): a[0] = 3
python2にはnonlocalがない しかたない。泥くさい
デコレーター
• 関数に機能を付加するような機構
• Javaのアノテーションのような表記
• 実体は関数を受け取って関数を返す関数
デコレータ
@log_output def hello(): print “Hello!”
デコレータdef log_output(func): # func関数を置き換える 新しい関数を生成 def wrapper(): print "function start" func() #元々の関数を呼び出し print "function end" return wrapper
hello = log_output(hello)と読み替えることができる。
クラス
• 非常にシンプル
• private, public などのアクセス修飾子なし
• すべてpublic
• __で始まるのはprivateだよ(慣習)
selfclass MyClass(object): def hoge(self): print "call hoge" !
mc = MyClass() mc.hoge() #等価なメソッド呼び出し MyClass.hoge(mc)
self# 通常の関数 def print_object(obj): print ......... !
# ターゲットオブジェクトを渡して実行 print_object(obj) !
#関数をクラスにbindすればメソッドに MyClass.print_object = print_object mc.print_object()
WSGI
• Web Server Gateway Interface
• WebサーバとWebアプリをつなぐための仕様
• WSGIに対応したアプリ
• WSGIに対応したWebサーバ
駆け足ですみません!
• 公式ドキュメントが充実してるってのが全てです