ラベル クラス の投稿を表示しています。 すべての投稿を表示
ラベル クラス の投稿を表示しています。 すべての投稿を表示

2009年10月20日火曜日

クラスのスーパークラスを取得する

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

import inspect

class A:
    pass
class B(A):
    pass
class C():
    pass
class D(C, B):
    pass

# クラスのスーパークラスをタプルで取得する
print D.__bases__

# クラスが継承しているクラス(自身も含め)をタプルで取得する
print inspect.getmro(D)

# インスタンスが属しているクラスを取得する
print D().__class__

実行すると
(<class __main__.C at 0xb7bed1dc>, <class __main__.B at 0xb7bed1ac>)
(<class __main__.D at 0xb7bed20c>, <class __main__.C at 0xb7bed1dc>, <class __main__.B at 0xb7bed1ac>, <class __main__.A at 0xb7cbc59c>)
__main__.D

詳細はドキュメントで

2009年10月17日土曜日

演算子のオーバーロード

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

# -*- 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月15日木曜日

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

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

class A:
    # 第一引数は絶対に必要
    def hello(self):
        print "hello"

a = A()
a.hello()

# このような使い方も出来る
# Aクラスを継承したクラスのインスタンスを引数に受け取る
A.hello(a)

詳細はドキュメントで

メソッドのオーバーロード

デフォルトの引数値を指定すると
オーバーロードのようになる

class A:
    def hello(self, s=""):
        print "hello", s

a = A()

a.hello()
a.hello("world")

詳細はドキュメントで

メソッドのオーバーライド

class A:
    def a(self):
        print "A"

class B(A):
    def a(self):
        A.a(self)  # スーパークラスのメソッドを使う
        print "B"

b = B()
b.a()

実行すると
A
B

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

詳細はドキュメントで

静的メソッド

似たようなものが2つある

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

# クラスメソッドの方は引数が1つ以上必要
class A:
    @staticmethod
    def sm():
        print "static"

    @classmethod
    def cm(cls):
        print "class"

A.sm()
A.cm()

a = A()

a.sm()
a.cm()

詳細はドキュメントで

2009年9月28日月曜日

privateやprotectedは

Pythonにアクセス修飾子はない

PEP 8 -- Style Guide for Python Code
非公開なメソッドとインスタンス変数にのみ、先頭にアンダースコアを1つ使って命名する。

サブクラスとの名前の衝突を避けるには、先頭にアンダースコアを2つ付けることで、Python の名前修飾ルールが行われる。
と書かれている

変数名などの先頭にアンダースコアを2つ付けると
privateのようになりますが消えたわけでない
class ABC:
    def __init__(self):
        self._x = 1
        self.__y = 2

abc = ABC()

print "_x =", abc._x
print "__y =", abc._ABC__y
print dir(abc)

実行すると
_x = 1
__y = 2
['_ABC__y', '__doc__', '__init__', '__module__', '_x']
__変数名 が _クラス名__変数名
と変化しているだけ

詳細はドキュメントで