3

numpy 配列が設定されるたびにその内容をチェックしたいと思います。これにpythonプロパティを使用できますか? 私のアプローチ:

import numpy as np

class Obj(): 
    def __init__(self):                                                                                 
        self._np_arr = None                                                                             

    @property                                                                                           
    def np_arr(self):                                                                                   
        if self._np_arr is None:                                                                        
            self._np_arr = np.ones(10)                                                                  
        return self._np_arr                                                                             

    @np_arr.setter
    def np_arr(self, value):
        if np.sum(value)>10:
            raise ValueError('Error message')                                                           
        self._np_arr = value

if __name__ == '__main__':
    o = Obj()                                                                                           
    print o.np_arr
    o.np_arr = np.zeros(10) # ok                                                                        
    o.np_arr = np.ones(10)*2 # not ok                                                                   
    print o.np_arr       

オブジェクトがまだ None のときに getter に入ります。np_arr が numpy 配列になると、ゲッターとセッターは機能しなくなります。

私は何を間違っていますか?

4

3 に答える 3

3

初めに。これを正しく行うのは困難です (私は不可能だと思います)。ここでのエラーは非常に単純で、新しいスタイル クラスである必要があります。class Obj()に置き換えるだけclass Obj(object)です。

ただし、ユーザーは引き続き適切に割り当てることができるため、これで問題が解決しない場合があります。

o.np_arr[:] = 2

を使用することで多少回避でき_np_arr.setflags(write=False)ますが、ユーザーはそのような操作をまったく使用できません。

編集:ndarrayをサブクラス化し、独自に定義__array_finalize__しておそらくそれを回避することもできます。ただし、それでもユーザーはそれを実行np.asarray(o.np_arr)して変更することができます...

独自のメソッドを提供してから、書き込み可能な配列で内部的に作業することで配列を「シミュレート」できると思います。しかし、100% 誰にでもできる、または少なくともエレガントな方法があるとは思えません。

于 2012-09-19T09:38:14.143 に答える
3

プロパティは新しいスタイルのクラスでのみ適切に機能します - に変更class Obj():するとclass Obj(object):、期待される出力が得られます:

$ python2 test.py
[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
Traceback (most recent call last):
  File "test.py", line 22, in <module>
    o.np_arr = np.ones(10) * 2
  File "test.py", line 16, in np_arr
    raise ValueError('Error message')
ValueError: Error message

Obj古いスタイルのクラス (Python 2 のデフォルト) の場合、への割り当てo.np_arrはセッターを呼び出しません。通常の属性割り当てのように動作し、プロパティを上書きします。

于 2012-09-19T09:33:24.387 に答える
0

'_' プレフィックスを使用して非公開であることを意味する一方で、get/set プロパティを定義して直接アクセスするようにすると、名前の競合が発生します o._np_arr

本当にプライベートにしたい場合は、明示的な get/setter ( o.set_arro.get_arr) を定義し、ユーザーにその場で変更しないように勧める必要があります。

于 2012-09-19T12:09:44.610 に答える