ラベル 特殊メソッド の投稿を表示しています。 すべての投稿を表示
ラベル 特殊メソッド の投稿を表示しています。 すべての投稿を表示

2010年1月10日日曜日

オブジェクトを比較し -1, 0, 1 を返す

組み込み関数の cmp を使う

# -*- coding: utf-8 -*-

# 戻り値は数値
# x < y なら -1, x == y なら 0, x > y なら 1
i = cmp("a", "b")

# クラスに特殊メソッド __cmp__ を定義すると
# 結果を変更できる
class A:
    def __cmp__(self, x):
        return 1

詳細はドキュメントで

2009年10月29日木曜日

オブジェクトのブール値を取得する

組み込み関数 bool で取得する
# -*- coding: utf-8 -*-

# 組み込み関数boolで取得できる
b = bool([])

# クラスに特殊メソッド __nonzero__ __len__
# を定義すると返す値を変更できる
# 二つとも定義すると __nonzero__ が優先される
class A:
    def __nonzero__(self):
        return False
class B:
    def __len__(self):
        return 0

b = bool(A())

b = bool(B())

詳細はドキュメントで

2009年10月27日火曜日

属性値アクセスをカスタマイズする

特殊メソッド __getattr__ __setattr__ __delattr__
をクラスに定義すると属性値アクセスをカスタマイズできる

class A:
    dic = {}
    def __getattr__(self, name):
        return self.dic[name]
    def __setattr__(self, name, value):
        self.dic[name] = value
    def __delattr__(self, name):
        del self.dic[name]

a = A()
a.x = 1
print a.x
del a.x

詳細はドキュメントで

2009年10月17日土曜日

コンテナ

# -*- coding: utf-8 -*-

# 特殊メソッド __getitem__ __setitem__ __delitem__
# を定義すると添字表記が出来るようになる
class A:
    def __getitem__(self, index):
        return "get item %d" % index
    def __setitem__(self, index, value):
        print "set item", index, value
    def __delitem__(self, index):
        print "del item", index

# 特殊メソッド __setslice__ __getslice__ を定義すると
# スライスが出来るようになる
class B(A):
    def __setslice__(self, i, j, sequence):
        print "set slice", i, j, sequence
    def __getslice__(self, i, j):
        return "get slice %d %d" % (i, j)

b = B()

print b[0]
b[1] = "123"
del b[2]
b[0:1] = "abc"
print b[2:4]

詳細はドキュメントで

演算子のオーバーロード

クラスに特殊メソッドを定義する

# -*- coding: utf-8 -*-

class A:
    # 二項算術演算
    def __add__(self, i):
        return 10 + i
    def __sub__(self, i):
        return 10 - i
    def __mul__(self, i):
        return 10 * i
    def __div__(self, i):
        return 10 / i
    def __truediv__(self, i):
        return 10 / i
    def __floordiv__(self, i):
        return 10 // i
    def __mod__(self, i):
        return 10 % i
    def __divmod__(self, i):
        return (10 / i, 10 % i)
    def __pow__(self, i):
        return 10 ** i
    def __lshift__(self, i):
        return 10 << i
    def __rshift__(self, i):
        return 10 >> i
    def __and__(self, i):
        return 10 & i
    def __xor__(self, i):
        return 10 ^ i
    def __or__(self, i):
        return 10 | i
    # 単項算術演算
    def __neg__(self):
        return -10
    def __pos__(self):
        return +10
    def __abs__(self):
        return abs(10)
    def __invert__(self):
        return ~10
    # 比較演算
    def __lt__(self, i):
        return 10 < i
    def __le__(self, i):
        return 10 <= i
    def __eq__(self, i):
        return 10 == i
    def __ne__(self, i):
        return 10 != i
    def __gt__(self, i):
        return 10 > i
    def __ge__(self, i):
        return 10 >= i

a = A()

print a + 2
print -a
print a < 4

# 2 + a
# 逆を出来るようにするには r をつけた特殊メソッドを定義する
# __radd__, __rsub__, __rmul__, __rdiv__, __rtruediv__
# __rfloordiv__, __rmod__, __rdivmod__, __rpow__, __rlshift__
# __rrshift__, __rand__, __rxor__, __ror__

# a += 2
# += などを出来るようにするには i をつけた特殊メソッドを定義する
# __iadd__, __isub__, __imul__, __idiv__, __itruediv__
# __ifloordiv__, __imod__, __ipow__, __ilshift__
# __irshift__, __iand__, __ixor__, __ior__

詳細はドキュメントで

2009年10月16日金曜日

オブジェクトが呼び出し可能オブジェクトか調べる

呼び出し可能オブジェクトとは
int() のように末尾に括弧をつけることのできるオブジェクトのこと
関数やメソッドなどは呼び出し可能オブジェクトである

# -*- coding: utf-8 -*-

# 呼び出し可能オブジェクトか調べる
b = callable(int)

# クラスに特殊メソッド __call__ を定義すると
# 呼び出し可能オブジェクトを模倣できる
class A:
    def __call__(self, a, b):
        return a + b

a = A()

i = a(1, 2)

詳細はドキュメントで

2009年10月11日日曜日

ファイルの読み書きをする

組み込み関数openなどでファイルオブジェクトを生成し
readやwriteメソッドで読み書きする
with文を使用すると自動的にファイルをクローズしてくれる

# -*- coding: utf-8 -*-

# ファイルに書き込む
with open("file", "w") as f:
    f.write("ハロー")

# ユニコードの場合はエンコードしてからファイルに書き込む
with open("file", "w") as f:
    us = u"ハロー"
    f.write(us.encode("utf-8"))

# ファイルを読み込む
with open("file", "r") as f:
    print f.read()

# for文を使い1行ずつファイルを読み込む
with open("file", "r") as f:
    for line in f:
        print line

# ファイルオブジェクトを継承する
class A(file):
    pass

エンコーディングを指定してファイルの読み書きする場合は
codecsモジュールを使う
# -*- coding: utf-8 -*-

import codecs

with codecs.open("shift-jis-file", "w", "shift-jis") as f:
    f.write(u"ハロー")

with codecs.open("shift-jis-file", "r", "shift-jis") as f:
    for line in f:
        print line

バイナリデータのファイルを読み書きする場合は
arrayモジュールを使う
import array
import os.path

with open("binary-file", "wb") as f:
    a = array.array("B", [1,2,3,4,5])
    a.tofile(f)

with open("binary-file", "rb") as f:
    a = array.array("B")
    a.fromfile(f, os.path.getsize(f.name))
    print a

with文を使用するには特殊メソッド__enter__と__exit__をクラスに定義し
コンテキストマネージャ型にしなければならない
class A:
    def __enter__(self):
        print "enter"
    def __exit__(self, exc_type, exc_val, exc_tb):
        print "exit"

with A() as a:
    print "hello"

詳細はドキュメントで

2009年10月10日土曜日

イテレータ型

クラスに特殊メソッド__iter__とnextメソッドを定義すると
forおよびin文を使えるようになる

class A:
    i = -1
    li = [1, 2, 3]
    def __iter__(self):
        self.i = -1
        return self
    def next(self):
        try:
            self.i += 1
            return self.li[self.i]
        except:
            raise StopIteration()

a = A()

for v in a:
    print v

print 1 in a

詳細はドキュメントで

2009年10月6日火曜日

コンストラクタ

特殊メソッド__init__を定義する
デストラクタは__del__

class A:
    def __init__(self):
        print "init"
    def __del__(self):
        print "del"

クラスを継承し__init__メソッドを定義した場合
明示的にスーパークラスの__init__メソッドを呼び出しさなければ
スーパークラスは初期化されない
class A:
    def __init__(self):
        print "A"

class B(A):
    def __init__(self):
        A.__init__(self)
        print "B"

b = B()

変更不能な型 (int, str, tuple など) を継承した場合
特殊メソッド__new__を定義する
class A(int):
    def __new__(self, i, j):
        return int.__new__(self, i + j)

a = A(4, 6)

print a

詳細はドキュメントで

オブジェクトの文字列表現を取得する

# -*- coding: utf-8 -*-

obj = 0.1

print str(obj)
print unicode(obj)
print repr(obj)
print `obj`

# クラスに特殊メソッド __str__ __unicode__ __repr__ を定義すると
# str() unicode() repr() の引数として渡すことが出来る
class A:
    def __str__(self):
        return "abc"
    def __unicode__(self):
        return u"abc"
    def __repr__(self):
        return "def"

a = A()

print str(a)

実行すると
0.1
0.1
0.10000000000000001
0.10000000000000001
abc

reprと``は同じ

詳細はドキュメントで

特殊メソッド

特殊メソッドとは __init__, __add__, __iter__ などのこと

クラスに特殊メソッドを定義することによって
演算子のオーバーロードなどをする事ができる

詳細はドキュメントで

2009年10月5日月曜日

文字列の長さを取得する

組み込み関数lenを使う

# -*- coding: utf-8 -*-

i = len("hello")

#正確には、文字列の長さではなく
#特殊メソッド__len__が返す値

class A:
    def __len__(self):
        return 34

a = A()
i = len(a)

詳細はドキュメントで

2009年9月27日日曜日

文字列を数値に変換する

# -*- coding: utf-8 -*-

# 文字列を数値に変換する
i = int("123")
f = float("1.23")
l = long("123l")
c = complex("123")

# 数値を文字列に変換する
s = str(123)
us = unicode(123)

# クラスに特殊メソッド __int__ __long__ __float__ __complex__ を定義すると
# int() long() float() complex() の引数として渡すことが出来る
class A:
    def __int__(self):
        return 10
    def __long__(self):
        return 100l
    def __float__(self):
        return 1.2
    def __complex__(self):
        return complex(10, 23)

a = A()

print int(a)

詳細はドキュメントで

ハッシュ値を取得する

# -*- coding: utf-8 -*-

i = hash("abc")

# 特殊メソッド__hash__を定義すればハッシュ値を変更できる
class A:
    def __hash__(self):
        return 12

a = A()

print hash(a)

詳細はドキュメントで