re:annkara

日々学んだことを書き留めておく。

Python覚え書き

パーフェクトPythonの昨日の続き。 初めてのPythonなどを参考にメモしてます。

with/asステートメント

try/finallyステートメントの代替として設計されたもの。 異なる点として、より幅広い用途に対応できるオブジェクトのプロトコルをサポートしている点が異なる。

基本的な使い方

with expression [as variable]:
    with block

expressionにはコンテキスト管理プロトコルをサポートするオブジェクトを戻すコード が入り、asを用いると、variableには何らかの値が代入される。 このとき、variableに代入されるのはコンテキスト管理プロトコルをサポートするオブジェクトではないことに注意。 このオブジェクトは、withブロックが開始され前に「前処理」をすることもあるし、終了後に、「後処理」をすることもある。

具体的な処理

with open("path/to/something") as f:

とした場合に、openはファイルオブジェクトを返し、それがfに代入される。 ファイルオブジェクトは、コンテキスト管理プロトコルをサポートしているため、 withブロックを抜けたら、自動的にファイルはクローズされる。

ちょっと紛らわしかったけど、要するに、expressionは評価された値じゃなくて、 オブジェクトを返して、asが使われていたら変数にオブジェクト代入するよっていう代物か。

コンテキストマネージャ

with/asの使い方は理解したけど、コンテキストマネージャって何だろう。 これは、初めてのPython見ても記述が見当たらなかった。

今まで整理した内容から考えると、ある操作をするときの状況・文脈で必ず行いたい前処理や後処理を 定義したもののことを言うのかな??

ちょっとここらへんまだ曖昧です。

とりあえず、独自のコンテキストマネージャを定義することができることは理解した。

クロージャ高階関数

クロージャ

すでに存在しない外側のスコープに属する変数を保持しているオブジェクトのこと。

def outer():
    x = 88          # 外側の変数
    def inner():
        print x      # 外側の変数を参照
    return inner  # 内側の関数オブジェクトを返す

action = outer() # 関数呼び出し。innerオブジェクトを返す。
action()              # 関数呼び出しにて、88と表示。

すでに存在しない、つまりはaction()を呼び出した際に、outer()は既に存在しないが、 inner()はouter()の変数xの値を保持している、ということ。

基本的にネストされた関数はわかりづらくなりやすいので、避けた方が無難ぽい。

高階関数

こっちは昨日の理解でよさげ。 なので、apply関数とか、map関数とかをサンプルに記述する。

def func(x, y, z): return x + y +z
    apply(func, (2, 3, 4,)) # 9と出力

list = [1, 2, 3, 4]

def inc(x): return x + 10
    map(inc, list) # [11, 12, 13, 14]と出力

apply関数は関数オブジェクトと引数を渡すことで、関数を実行してくれる。 map関数は、関数オブジェクトとシーケンス型のオブジェクトを渡すことで、 一つ一つの要素に関数を適用して、リストを生成する。

デコレータ

とりあえず、以下のリンクを見る。

Python 用語集

(デコレータ) 別の関数を返す関数で、通常、 @wrapper 構文で関数変換として適用されます。 デコレータの一般的な利用例は、 classmethod() と staticmethod() です。 デコレータの文法はシンタックスシュガーです。次の2つの関数定義は意味的に同じものです:

def f(...):
    f = staticmethod(f)

@staticmethod
def f(...):

とりあえずここまでは理解。 具体的なサンプルコードを見てみる。 以下のリンクを見てみる。

Pythonのデコレータを理解するための12Step

具体的なサンプルコードはリンク先を見てもらうとして、 要するにデコレータっていうのは、関数本体に手を入れることなく、何か別の事をやって欲しいと思ったときに、 それ専用のクロージャを作ってあげて、何かごにょごにょして、ハイじゃあ元の関数さんあなたの仕事してねって 感じの処理か。

それぞれの関数内で、ごにょごにょする関数を呼び出してもいいけど、@関数名でデコレートしとけば、 見た目奇麗になるでしょ、てな感じで今は理解しておこう。 (ここら辺からだいぶ適当になる、かも)

ディスクリプタ

参考にしたリンク先
ディスクリプタ HowTo ガイド
Python を支える技術 ディスクリプタ編 #pyconjp

__get__,__set___,__delete__

上記、3つのメソッドを定義したオブジェクトのこと、、、、

とまではわかったけど、それ以降は全然理解できない。

ちゃんとPythonにおけるクラスとかの仕組みを理解しないとだめな気がする。 ということで、もいっかい勉強し直してからここは戻ってこよう。

メソッド関連の話もそれからということで。

昨日今日とPythonの学習してきたけど 今まで言語の表面的な部分しか全然触ってきてなかったんだなと痛感しました。

それでも内部的な仕組みに少しでも触れることができたので、 今後とも精進していきたいです。