みんPy(改訂版) 読書メモ Chapter 10

Chapter 10 例外処理

例外の捕捉

try〜except文を使う。elsefinallyもある。

try:
    hoge()
    fuga()
except IOException:
    print 'ERROR!!'
else:
    # 例外が一つも発生しなかったとき(この例ではIOException以外の例外が発生した場合には実行されない)
    pass
finally:
    # 例外が発生してもしなくても実行される
    pass
  • except は、何も指定しない場合はすべての例外をキャッチする。
  • except の後に指定する例外型は、括弧で囲って、カンマ区切りすることで複数指定できる。
  • except に指定する例外型の後に、カンマで区切って変数名をしていすることで、捕捉した例外オブジェクトを変数に代入できる。
  • Python 3〜は、変数代入の場合感まではなくasを使う(2.6〜使用可能)

例外のチュートリアル

例外発生

raiseを使う。

raise 'SomeError'    # 文字列そのものをraiseできる
raise ValueError('a value error occured')    # 例外オブジェクトもraiseできる。

tracebackモジュール

スタックトレースを扱うときは、標準モジュールtracebackを使う。

with

ファイル操作などでwith文を使うと、お決まりの例外処理等を行わずに処理が成功したときのみ実施するような処理をかける。

with open(filename) as f:
    # ファイルがオープンしたときのみ以下が実行される
    for line in f:
        print f
# ファイルのクローズは自動で実行される。

参照:

None

値を持たないことを表す。

  • if文の条件式とするとFalseと評価される
  • 戻り値を返さない関数/メソッドを変数に代入するとNoneとなる。

みんPy(改訂版) 読書メモ Chapter 9

Chapter 9 クラスの継承と高度なオブジェクト指向機能

スーパークラスの指定

class <クラス名>(<スーパークラス名>[,スーパークラス名2,...]):
    # classdefs
    :
    :

多重継承が可能。

オーバーライド

スーパークラスのメソッドと同名のメソッドをサブクラスで改めて定義する(Pythonの関数/メソッドの同一性は名前だけで判断される(たぶん))。

親クラスの初期化メソッド/メソッド呼び出し

初期かメソッドのオーバーライドをしても、自動で親クラスの初期化メソッドは呼び出されない。 クラス名指定または、組み込み関数 super() を使用する( super() は、新スタイルクラスでのみ使用可能)

class Super(object):
    def __init__(self):
        print 'initializing Super'

class Sub1(Super):
    def __init__(self):
        Super.__init__(self)        # クラス名指定で__init__()呼び出し。この場合はselfを第一引数に渡す必要がある。
        print 'initializing Sub1'

class Sub2(Super):
    def __init__(self):
        super(Sub2,self).__init__()    # super()関数による__init__()呼び出し。
        print 'initializing Sub2'

super()関数のドキュメント

新スタイルクラス

ver. 2 系では、object または組み込み型を親クラスとするクラスを作成することで新スタイルクラスとなり、使用できる機能が増える。(ver. 3 系ではすべてのクラスが新スタイルクラスとなる)。

スロット

__slots__ に文字列のリストを代入することにより、そのクラスに追加できるアトリビュートを制限することができる。

class Cls(object):
    __slots__ = ['a','b']

    def __init__(self):
        self.a = 1

c = Cls()
print c.a
c.b = 2
print c.b
c.c = 3        # ここでエラーとなる。
プロパティ

アトリビュートの設定時にメソッドを経由させることができる。

class Cls(object):
    
    def __init__(self):
        self.__value = 1
        return
        
    def set_value(self, value):
        print 'set value to ' + str(value)
        self.__value = value
        return
    
    def get_value(self):
        print 'get the value ' + str(self.__value)
        return self.__value

    value = property(get_value,set_value)

property() 関数のドキュメント

特殊メソッド

クラスに特殊メソッドを定義することで演算子オーバーライドなどを実現できる。

残術演算子

算術演算子のオーバーライドは、以下の特殊メソッドを定義する。いずれも2つの引数(self と演算対象)をとる。

  • __add__(self, other) : +
  • __iadd__(self, other) : +=
  • __sub__(self, other) : -
  • __isub__(self, other) : -=
  • __mul__(self, other) : *
  • __imul__(self, other) : *=
  • __div__(self, other) : /
  • __idiv__(self, other) : /=
  • __and__(self, other) : & (ビットAND)
  • __or__(self, other) : | (ビットOR)
比較演算子
  • __cmp__(self, other) : self < other なら負値、self == other なら 0、self > other なら正値を返却する。
  • __eq__(self, other) : 等しい場合に True、等しくない場合に False を返却する。
  • __ne__(self, other) : 等しくない場合に True を返却する。
  • __lt__(self, other) : self < other が成り立つ場合に True を返却する。
  • __le__(self, other) : self <= other が成り立つ場合に True を返却する。
  • __gt__(self, other) : self > other が成り立つ場合に True を返却する。
  • __ge__(self, other) : self >= other が成り立つ場合に True を返却する。

個別の演算子が定義されていればそちらが優先的に呼び出され、そうでない場合 __cmp__()が呼び出される。

型変換

型変換を行う組み込み関数の引数として指定された場合に呼び出される。 いずれも一つの引数 (self) をとる。

  • __int__(self) : int()
  • __float__(self) : float()
  • __str__(self) : str()print 文で表示する場合などにも呼び出される。
  • __repr__(self) : インタラクティブシェル等での文字列表現を取得する際に呼ばれる。__str__() が定義されていない場合、代わりに呼び出される。
  • __unicode__(self) : unicode()。このメソッドが定義されていない場合は、__str__()によって変換後、デフォルトエンコーディングユニコード文字列化される。
コンテナ型
  • __len__(self) : 組み込み関数 len() の引数に指定された場合に呼び出される。
  • __getitem__(self, key) : キーによる要素の参照時に呼ばれる。 e.g.) li[1] dic['key']
  • __setitem__(self, key, value) : キーによる要素の設定時に呼ばれる
  • __delitem__(self, key) : del文による要素の削除を行うときに呼ばれる。
  • __iter__(self) : 組み込み関数 iter() から呼ばれる。イテレータオブジェクト(next()メソッドを実装する)を返却する。
  • __contains(self, item) : in にて、要素が存在するかを検査する際に呼ばれる。True/Falseを返却する。
アトリビュートのアクセス
  • __getattr__(self, name) : オブジェクトに存在しないアトリビュートが参照されるときに呼び出される。
  • __getattribute__(self, name) : 新スタイルクラスでのみ使用できる。アトリビュートが参照されるとき無条件に呼び出される。
  • __setattr__(self, name, value) : アトリビュートに代入を行うときに必ず呼び出される。
その他
  • __call__(self[, args...]) : オブジェクト自体が関数のように呼び出された場合に呼ばれる。
  • __del__(self) : オブジェクトがメモリ上から消去されるときに呼び出される。del および ガベージコレクション時に呼ばれる。

みんPy(改訂版) 読書メモ Chapter 8

Chapter 8 クラスとオブジェクト指向開発

インスタンス

コンストラクタは <クラス名>()Javaみたいな new キーワードは不要。 定義がわは __init__() メソッドを定義する。これが初期化時に呼び出される。

selfキーワード

メソッドの第一引数は必ずメソッドが呼び出されたインスタンスを示す self となる。

アトリビュート

アトリビュートは、オブジェクトに対して変数の代入を行うことで初めて定義される。

アトリビュートの隠蔽

アトリビュートについて、アンダースコアで始まるものは、外部から直接編集されたくない属性であることを(コーディング規約的に)示す。 アンダースコア2連続から始まるアトリビュートは、内部的にアトリビュート名を自動的に変更されるため、外部からの直接編集を回避できる(名称が変わるだけなので、意図的にその回避策を無効化することはできる)。

みんPy(改訂版) 読書メモ Chapter 7

Chapter 7 華麗で短いプログラミング

リスト内包表記

[]で囲って、<式> for <変数名> in <シーケンスetc> で、シーケンスの各要素に対して式を適用した値をすべて保持するリストを作成できる。 また、`<式> for <変数名> in <シーケンスetc> if <条件式> で、シーケンスから条件式にあう要素のみを取り出して、式を適用してリストにする。

for文は複数個書ける。複数書いた場合はネストしたfor文のように動く。

イテレータ

iterable なオブジェクトからイテレータを取得するには、iter() 関数を使用する。組み込み型はすべて iterable。

next() メソッドをもち、次の要素がない場合 StopIteration を投げる(Pythonでは次の要素があるかをチェックするメソッドは定義せず、この StopIteration によって判断する模様)。

ジェネレータ

定義はほぼ関数と同じ。値を返すときに yield を使用する。ジェネレータを呼び出すとジェネレータオブジェクトが返却され、イテレータと同様に next() メソッドで次々に値を取り出すことができる。

def fibonacci():
    yield 0
    curr = 1
    prev = 0
    while True:
        yield curr
        preprev = prev
        prev = curr
        curr+=preprev

gen = fibonacci()

for i in range(10):
    print gen.next()

# => 10個のフィボナッチ数列が表示される。

みんPy(改訂版) 読書メモ Chapter 6

Chapter 6 ファイル処理

open/close

ファイルを開くには open() 関数を使う。ファイルオブジェクトが返る。

f = open(<ファイル名>, <モード>)    # モードには "r" (read) "w" (write) "a" (append) などを指定。

ファイルのクローズは、ファイルオブジェクトの close() メソッドを使用する。閉じなくても、終了時かGC時に閉じられる。

読み込み/書き込み

f.read(size)        # ファイルから size 分読み込み
f.readline(size)    # ファイルから size を上限として、一行読み込み
f.readlines(size)   # ファイルから size を上限として、行のリストを読み込み
f.write(string)     # ファイルに string を書き込み
f.writelines(sequence)   # ファイルに sequence の要素を1行として書き込み

forでまわすなら、ファイルオブジェクト自体が iterable なので、以下が可能

for line in f:
    # do something

日本語ファイルの読み書き

codecs モジュールの open() 関数を使うと、文字コードを指定してユニコード文字列としてファイルの内容を扱うことができるようになるので便利。

みんPy(改訂版) 読書メモ Chapter 5

Chapter 5 組み込み型を使いこなす

文字列フォーマット

<文字列> % <タプル> または <文字列> % <辞書>でprintfスタイルの文字列のフォーマットが可能。

u"%d回生きた%s" % (10000,"犬")    # => "10000回生きた犬"
u"%(count)d回生きた%(animal)s" % {"count":1000000,"animal":"猫")    # => "1000000回生きた猫"

Python標準ライブラリドキュメント

スライス

スライスのステップ数指定

スライスにはステップ数を指定することもできる。

[1,2,3,4,5,6,7,8,9,][::3]    # => [1,4,7]
スライスによる一部要素の入れ替え
li = [1,2,3,4,5]
li[1:4] = ["two","three","four"]    # => li = [1,"two","three","four",5]
スライス指定での要素の削除
li = [1,2,3,4,5]
del li[2:]    # => [1,2]

アンパック代入

リストやタプルの要素を個別の変数にアンパックして代入できる

one, two = (1, 2)    # one=1 two=2 と同様
three, four = 3, 4    # カンマ区切りの値の列挙はタプルとして扱われる

シーケンス型 (リストやタプル、文字列など)

参照

set

参照 |や&といった演算子を使うこともできる。

辞書

参照

in

シーケンス中に要素が含まれるかをTrue/Falseで返す。文字列中に部分文字列が含まれるかもチェックできる。

シーケンスとループカウンタ

シーケンスをイテレートしながら同時にカウンタも使う場合はenumerate()関数が便利。

for cnt, item in enumerate(seq):
    print cnt, item

zip()関数

2つのシーケンスの要素をタプルにしたリストにして返す。要素数が異なる場合は、少ない方にあわせる。

for name,email in zip(namelist,emaillist):
    print name+":"+email

引数リスト

def foo(a,b,*vals):
    print a, b, vals    # valsは複数要素をとれる。タプルとして関数内で使用できる。

foo(1,2,100,200)        # => 1 2 (100, 200)

引数マップ

def bar(a,b, **args):
    print a,b,args    # argsはマップとなる

bar(1,2,c=100,d=200)  # => 1 2 {'c': 100, 'd': 200}

文字列

  • 8ビット文字列->ユニコード文字列
    • unicode() 関数
    • decode() メソッド
  • unicode文字列->8ビット文字列
    • encode() メソッド
スクリプトファイルのエンコード指定

ファイルの一行目に以下のようなコメントを書く

# coding: <エンコード名>
# coding = <エンコード名>
# -*- coding: <エンコード名> -*-
デフォルトエンコーディング

デフォルトエンコーディング設定は、sysモジュールの setdefaultencoding() 関数を使う。 sitecustomize.pyに環境の設定をかける。

Mac OSXデフォルトのPythonでEclipse PyDevを動かす

MacにデフォルトでPythonインストールされていますけど、そのままだとPyDevを動かせなかったのでメモ。

前提

EclipseにPyDev導入済み。

現象

インタープリタの設定をしようとして、デフォルトのPythonディレクトリ(/System/Library/Frameworks/Python.framework/Versions/X.X/lib/pythonX.X/*)を選択した場合、Python stdlib not found or stdlib found without .py files. というエラーメッセージを受け取ることになる。

対応

Python公式サイトから、ソースコードリリースをダウンロードして、Libsフォルダの中身を、上述のpythonX.Xフォルダにコピーする。 で、PyDevのインタープリタ設定を再度実施。

参考:PyDev Eclipse Python interpreters Error: stdlib not found - Stack Overflow:

(でも、本当は別途Pythonをインストールした方がよいのでしょうね)。