5

私は次のことを機能させようとしていますが、成功していません:

単位付きの量の代数を実装するために、独自の型Unit(組み込み型から継承) を定義しました。float次のように処理します。

class Unit(float):
"""provide a simple unit converter for a given quantity"""

    def __new__(cls, unit, num=1.):
        return super(Unit, cls).__new__(cls, num)

    def __init__(self, unit, num=1.):
        """set up base unit"""
        self.unit = unit

    def __str__(self,):
        return '{:s} {:s}'.format(super(Unit, self).__str__(), self.unit)

    def __rmul__(self, other):
        print 'rmul: {:f}'.format(super(Unit, self).__rmul__(other))
        return Unit(self.unit, super(Unit, self).__rmul__(other))

    def to(self,target):
        fun_conv = _conv(self.unit, target)
        return  Unit(target, num=fun_conv(self))



c = 3e8 * Unit('m/s')   # this will 1) create a Unit instance with magnitude '1' and unit 'm/s',
                        #           2) invoke __rmul__ to return a new instance with number 3e8 and unit 'm/s' to variable 'c'
print c.to('km/s')      # returns 3e5 km/s

ただし、これは左オペランドの__rmul__場合にのみ呼び出されます。float私がこのようなものを作るなら:

velocities = np.array([20, 10]) * Unit('m/s')

その後Unit.__rmul__は呼び出されず、値が 1.0のプレーンのように扱われたnumpy ndarrayため、同じものが返されます。Unit('m/s')float

私が期待しているのは: afterndarray * Unitに似た関数Unit.toを ndarray のインスタンスにメソッドおよび属性としてアタッチunitできるため、さらに呼び出しndarray.toてコピー (または可能であれば、メモリ効率のために変更されたバージョン) を返すことができます。新しい値と単位に関連付けられた元の ndarray の。続行するにはどうすればよいですか?

私が知っていて検索したことによると__mul__、左側のオペランドの は の間に優先され*ます。つまり、インタープリターはLO.__mul__()最初にチェックし、失敗した場合は に進みRO.__rmul__()ます。numpy.ndarray.__mul__オーバーライドがどれほど複雑になるか、および ndarray が他のオブジェクトに作用するという規則に違反した場合に大きな混乱が生じるかどうかが本当にわからないため、オーバーライドしたくありません。

__mul__そして、実際には、 を定義するコードがどこにあるのかさえわかりませんndarray。私は単に使用inspect.getsource(np.ndarray)しましたが、成功しませんでした。なぜこれで失敗するのですか?例外はほとんどありませんでしたIOError

ご心配ありがとうございます!

4

1 に答える 1

2

float から継承せず、代わりに新しいタイプ ラッピング float を作成する場合 (そのため、float._ mul _(yourtype) は機能しません)、rmul は希望どおりに機能します。もちろん、ラッピングは無料ではありません...そして、型がサポートするすべての操作を実装する必要があります。

class T(object):
  def __init__(self, val):
    self.val = val

  def __mul__(self, x):
    print("mul")
    return T(self.val*x)

  def __rmul__(self, x):
    print("rmul")
    return T(self.val*x)

  def __repr__(self):
    return str(self.val)

>>> t = T(2)
>>> t * 2
mul
4
>>> 2*t
rmul
4
于 2013-07-15T07:39:21.870 に答える