2011-07-31 29 views
8

私は2Dベクトルを表現するための単純なクラスを実装しています。ここのは、関連するビットです:私はTypeError: 'NoneType' object is not callableを得るPython Strange Error: "TypeError: 'NoneType'オブジェクトが呼び出し可能ではありません。

a = Vector(1, 1) 
b = Vector(2, 2) 
a + b 

class Vector: 
    def __init__(self, x, y): 
    self.vec_repr = x, y 

    def __add__(self, other): 
    new_x = self.x + other.x 
    new_y = self.y + other.y 
    return Vector(new_x, new_y) 

    def __getattr__(self, name): 
    if name == "x": 
     return self.vec_repr[0] 
    elif name == "y": 
     return self.vec_repr[1] 

その後、私のようなものを持っています。エラーは特定の行にあるとマークされていないので、これは特に奇妙なので、どこを見るかはわかりません!

私はいくつかの実験を行い、それがa+bという行にあることを発見しました。また、次のようにクラスを再作成すると、次のようになります。

​​

エラーが消えます!

これに似たエラーに関する多くの質問があります。すべては、変数によってどこかの関数名が上書きされているようですが、どこでこれが起こっているのか分かりません。別の手がかりとして

、私は何か他のものへ __getattr__()のデフォルトの戻り値の型を変更したとき - STR、例えば - エラーは何が起こっているのと TypeError: 'str' object is not callable

任意のアイデアにモーフィング? __getattr__()の動作がわかりませんか?

答えて

11

__getattr__は、xy以外の属性に対しては何も返さず、AttributeErrorを発生しません。したがって、__add__メソッドを参照すると、__getattr__Noneを返し、エラーになります。

__getattr__を他の属性の戻り値にすることでこれを修正できます。実際には、__getattr__が、処理されないすべての属性のスーパークラスからメソッドを呼び出すようにする必要があります。しかし、実際には__getattr__がここで使うのは間違っています。これは、控えめに使用する必要があります。たとえば、動的ディスパッチには__getattr__が不可欠です。しかし、あなたのケースでは、xyの値はよく知られており、コードが実行される前に明確に定義されています。

適切な解決策は、xyのプロパティを作成し、__getattr__を実装しないことです。

@property 
def x(self): 
    return self.vec_repr[0] 

@property 
def y(self): 
    return self.vec_repr[1] 
+0

とちょうど全体像のために、それは私が__coerce__' 'に慣れていないんだけど、私はそれがどうなるのかを推測することができ、そしてなぜそれが呼ばれることになる__coerce__' –

+0

@yi_H'呼び出そうとしました! –

+0

Ooh。うわー、ありがとう。私は__getattr __()が他の場所で属性を見つけられなかったときに__getattr __()に落ちると考えました。まあ、これは非常に恥ずかしいです。 – Slubb

関連する問題