スポンサーサイト

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    クラスの四則演算を制御する

     Pythonでクラスを定義した際、なんとそのクラスを四則演算に含めた時の挙動を制御できるようです(これ知った時は感動して舞い上がっちまいましたw)
     例えば、3次元ベクトルを扱うカスタムベクタクラスを定義したとします(これを仮にVecクラスとします)。
    ベクトルの乗算の性質として
    • スカラ値を掛けた場合、スカラ値倍したベクトルを返す
    • ベクトルを掛けた場合、外積の場合はベクトル、内積の場合はスカラ値をそれぞれ返す
    と言う感じに、掛けた値によって結果がかわりますね。
     このようなルーチンを、クラスの乗算を定義するメソッドで制御してやる事ができるみたいです。
     因みに乗算を定義するメソッドは__mul__です。

     ではお試しで早速
    class Vec( tuple ):
        '''ベクトル演算をするのに便利なカスタムベクタークラス。'''
        def __init__( self, arg ):
            errMsg = 'Vec class must receive a type tuple or list that has 3 float or int values.'
            if not type( arg ) in ( list, tuple ):
                raise TypeError, errMsg
            # 引数に与えられたタプルの要素が3つ以外の場合にエラーを返す。
            if len( arg ) != 3:
                raise TypeError, errMsg
            # タプルの要素がFloatかInt以外ならエラーを返す。
            for a in arg:
                if self.isScalar( a ):
                    continue
                raise TypeError, errMsg
    
        def isScalar( self, value ):
            if type( value  ) in ( float, int ):
                return True
            else:
                return False
    
        def __mul__( self, value ):
            '''ベクトルの乗算メソッド'''
            if self.isScalar( value ):
                # スカラ値の乗算メソッド
                return Vec( [ x*value for x in self ] )
            elif isinstance( value, Vec ):
                # ベクターの乗算(外積)メソッド
                return Vec( (self[1]*value[2]-value[1]*self[2], self[2]*value[0]-value[2]*self[0], self[0]*value[1]-value[0]*self[1]) )
            else:
                # それ以外の値の場合はエラーを返す。
                raise TypeError, '%s and Vec class can not operate a multiply sequence.' % type( value )
    
        def __rmul__( self, value ):
            return self.__mul__( value )
    
        def dotProduct( self, value ):
            '''ベクトルどうしの内積を算出するメソッド'''
            if not type( value ) in ( list, tuple, Vec ):
                raise TypeError, 'dotProduct method can operate only list, tuple, or Vec class.'
            return self[0]*value[0] + self[1]*value[1] + self[2]*value[2]
    
    ちょっと長くなっちました。

     上記スクリプトの中で、__mul__メソッドと__rmul__メソッドでそれぞれ掛ける場合と掛けられる場合の挙動を定義してます。
     と言っても掛ける時も掛けられるときも挙動は基本的に一緒なんで、__rmul__メソッドでは__mul__を呼び出して終了すると言う横着をしてます(^^;
    具体的に使用してみると・・・
    a = Vec( (1, 0, 0) )
    b = Vec( (0, 1, 0) )
    a * b
      >(0, 0, 1)
    b * a
      >(0, 0, -1)
    
    a * 10
      >(10, 0, 0)
    5 * a
      >(5, 0, 0)
    素晴らしい(><)
     因みに__rmul__を定義しておかないと、5 * aの結果が変わってしまいます、ご注意を。
    同様に
    • 加算は__add__及び__radd__
    • 減算は__sub_及び__rsub___
    • 除算は__div__及び__rdiv__
    • って感じで四則演算の挙動を定義できます。

       他にも累乗演算子(**:__pow__)やOR、AND(__or__, __and__)なんかもあります。
      詳しく知りたい方はココをご覧ください~


       いやぁ、Python楽しいっすね~ ←世間知らず
      スポンサーサイト

    コメントの投稿

    非公開コメント

    プロフィール

    Eske

    Author:Eske
    萌えイラストレーターを目指す3DCGイラストレーター。
    現在ポケモンカードゲーム、ガンダムトライエイジ、ガンダムコンクエスト、妖怪ウォッチとりつきカードゲームなどで3DCGを使用したイラストレーターとして参加中。

    主にここでは日々気づいたメモなんかを残してます。
    イラストのお仕事も受け付けております。ココからアクセスできますので、お気軽にご相談下さい。

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR
    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。