2

"Parray"というndarrayのサブクラスを作成しました。これはpと次元数の2つの引数をとります。それ自身でうまく動作します。今、私は(オブジェクトp =パラメータを渡すことによって、すべての空想新しいarray_finalizeなどせずにParrayを継承するSirPlotsAlotと呼ばれるクラス、パラメータの私のプログラムを共有セットでnumpyサブクラスは、Pythonを継承するクラスから__new__への引数を受け入れません。

import numpy as np 

class Parray(np.ndarray): 
    def __new__(self, p = Parameters(), dimensionality = 2): 

     print "Initializing Parray with initial dimensionality %s..." % dimensionality 

     self.p = p # store the parameters 

     if dimensionality == 2: 
      shape = (p.nx, p.ny) 
      self.pshape = shape 
     elif dimensionality == 3: 
      shape=(p.nx, p.ny, p.nx) 
      self.pshape = shape 
     else: 
      raise NotImplementedError, "dimensionality must be 2 or 3" 

     # ...Set other variables (ellided) 

     subarr = np.ndarray.__new__(self, shape, dtype, buffer, offset, strides, order) 
     subarr[::] = np.zeros(self.pshape) # initialize to zero 
     return subarr 
... 

class SirPlotsAlot(Parray): 
    def __init__(self, p = Parameters(), dimensions = 3): 
     super(SirPlotsAlot, self).__new__(p, dimensions)  # (1) 

オブジェクトを作成したいです) 行ったり来たり。私は(ファイルがauxiliary.pyである)を入力するとき

は今、:

import auxiliary 
from parameters import Parameters 
p = Parameters() 
s = auxiliary.SirPlotsAlot(p, 3) 

は素敵な "初期次元3で初期化Parray" を得ることを期待し、私の代わりに、 "2" を取得します。私が入力した場合しかし:

import auxiliary 
s = auxiliary.SirPlotsAlot() 

は私が

---> 67    shape = (p.nx, p.ny) 
"AttributeError: 'int' object has no attribute 'nx'" 

を取得するには、 "p" はそうでないint型、と考えています。私が周りを遊んでいると、私は一見無関係の奇妙なエラーをたくさん得ることができます。それが思うintは "2"です。私は完全に失われています。

私は#(1)コメント(スーパーコール)の有無にかかわらず試しました。 ":新しい()を正確にとる2つの引数(1与えられた)例外TypeErrorが"、「とValueError:必要以上0、:遊んでから

その他のエラーは、 " 'リスト' オブジェクトは、 'P' 何の属性を持っていないはAttributeError" を含み(私はの新しいの引数を* argsに置き換えました。私は非常によく分かりません)。

+1

もし 'p'がintであるとPythonが考えるなら、それはおそらく正しいでしょう。 'pdb'を使ってその行にブレークポイントを置き、あなたが持っているものを見てください。スタックトレースを行って、そこにどのように到達したかを確認します。トレースに記載されているファイルが、そこにあるはずだと思っている場合は、非常に慎重に注意してください。ライブラリのパスが多少間違っていると、複数の人が混乱してしまいました。 –

+3

あなたのコードのどこかに問題があるかもしれないという1つの問題は、 '__init__'の" p = Parameters() "呼び出しがおそらくあなたが思っていることをしないということです。 'Parray .__ new__'が呼び出されるたびに新しいParametersインスタンスを作成するのではなく、関数が最初に宣言されたときに* one *を行います。 IOWでは、各Parrayはパラメータインスタンスを渡さないとParameterインスタンスを共有しますが、これはあなたの意図であるとは思われません。 [これはここでどのように問題が起こるか分かりませんが、別の場所で問題を引き起こす可能性があります。] – DSM

+4

'__new __()'と '__init __()'を組み合わせて使用​​することは、あまり言い方がありません。なぜParrayクラスで '__new __()'をもう一度使っていますか?これは普通の古い '__init __()'メソッドのようです。それを '__new __()'と書く理由はありません。なぜクラスに属性を格納していますか? ( '__new __()'では、最初のパラメータはインスタンスではなくクラスへの参照です。 – kindall

答えて

1

私はちょっとエコーし、 "__new__を使わないでください"と言うつもりです。 Parray.__new__メソッドは初期化のように見えますが、サブクラスのように__init__を使用する必要があります。

+0

本当ですか?私は 'np.ndarray'をサブクラス化すると思いますが、あなたは' __init__'ではなく '__new__'を使うことになっています。http://docs.scipy.org/doc/numpy/user/basics.subclassing.html – keflavich

+0

これはまさに私のものでした考えていました。だからこそ、私の新しいndarrayサブクラスのすべてのサブクラスがndarrayの規則に従う必要がないことを望んでいたのです。私が現在検討している探検の1つの道は、Parrayをndarrayとして扱うことです。簡単な修正として、クラスの初期化で変数のデフォルトのステートメントを削除し、ヘルパー関数を作成しました。NewSirPlotsAlot(​​p = Parameters()dimensions = 3):return SirPlotsAlot(​​p、dimensions)。私が欲しいものではありませんが、それはうまくいくようです。 – Erasmus

+0

@keflavich:良い点。私は '__new__'を必要とする多くのPythonコードを見ていません。あなたがおそらくしたくないことは、既に呼び出されているので、 '__init__'から' __new__'を呼び出すことです。 –