8

ここに書くのは初めてです、メッセージが的外れであったり、長すぎたりしたらすみません。

必要に応じてオブジェクトの属性がどのように取得されるかについて、もっと理解したいと思っていました。そこで、「Data Model」というタイトルの Python 2.7 のドキュメントを読んで、会って、その動作を理解している__getattr__かどうかを確認するために、これらの単純な (そして不完全な) 文字列ラッパーを書きました。

class OldStr:
  def __init__(self,val):
    self.field=val

  def __getattr__(self,name):
    print "method __getattr__, attribute requested "+name

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

  def __getattr__(self,name):
    print "method __getattr__, attribute requested "+name

ご覧のとおり、古いスタイルと新しいスタイルのクラスであることを除いて、それらは同じです。引用されたテキスト__getattr__には「属性ルックアップで通常の場所に属性が見つからなかったときに呼び出される」と書かれているため、これらのクラスの 2 つのインスタンスで + 操作を試して、同じ動作を期待して何が起こったのかを確認したかったのです。

しかし、私が得た結果は私を少し当惑させました:

>>> x=OldStr("test")
>>> x+x
method __getattr__, attribute requested __coerce__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable

良い!のメソッドを定義していませんでした__coerce__(ただし、 のリクエストを期待していましたが、気にしないでください__add__:)、__getattr__関与して役に立たないものを返しました。しかしその後

>>> y=NewStr("test")
>>> y+y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'NewStr' and 'NewStr'

__getattr__+ のような組み込み演算子を使用すると、古いスタイルのクラスと新しいスタイルのクラスの間でこの非対称の動作が発生するのはなぜですか? 誰かが何が起こっているのかを理解するのを手伝ってくれませんか? ドキュメントを読む際の私の間違いは何ですか?

どうもありがとう、あなたの助けが強く感謝されます!

4

3 に答える 3

5

new-style クラスの特別なメソッド ルックアップ を参照してください。

特別なメソッドは、クラス オブジェクト、インスタンス オブジェクトで直接検索され、その結果バイパスさ__getattr__()れます。__getattribute__()まったく同じ理由で、instance.__add__ = foobar機能しません。

これは、属性へのアクセスを高速化するために行われます。特別なメソッドは非常に頻繁に呼び出され、それらを標準のかなり複雑な属性ルックアップの対象にすると、インタープリターの速度が大幅に低下します。

古いスタイルのクラスの属性ルックアップはそれほど複雑ではありません (特に古いスタイルのクラスは記述子をサポートしていません)。そのため、古いスタイルのクラスで特別なメソッドを異なる方法で扱う理由はありません。

于 2010-08-05T15:00:21.223 に答える
1

あなたの__getattr__関数は何も返していません。__getattr__なぜ古いスタイルのクラスが を探す前に を実行しているのかはわかりませんが、そう__add__であり、これは である戻り値を呼び出そうとしていますNone

新しいスタイルのクラスはそれを正しく行っています: 定義__add__していないので、それらを追加する方法がわかりません。

于 2010-08-05T14:47:18.777 に答える
0

Python ドキュメントからの詳細情報:

http://docs.python.org/reference/datamodel.html#customizing-attribute-access

于 2010-08-05T14:49:29.707 に答える