2

メンバー関数の属性にアクセスしようとしていますが、なぜアクセスできるのか理解できません__dict__

class A(object):
    def fA(self):
        print A.fA.x 
    fA.x = 2

A.fA.__dict__['x'] = 3 
#A.fa.x #AttributeError: 'instancemethod' object has no attribute 'x'
A.fA.x = 4 

'直接'にアクセスしようとすると、なぜAttributeErrorが発生するのですか?

4

2 に答える 2

3

instancemethodオブジェクトの実装方法のためです。非標準の属性へのアクセスを許可しない非標準の属性ゲッターを使用します。

于 2012-07-29T22:01:05.843 に答える
2

なぜこれを行うのかはわかりませんが...

A.fA は実際には関数 fA とは完全に別のオブジェクトです。時計:

>>> class A(object):
...   def fA(self): pass
...   print fA
... 
<function fA at 0x10f1c2a28>
>>> A.fA
<unbound method A.fA>

ご覧のとおり、A.fA は関数ではなく「バインドされていないメソッド」です。「バインドされていない」とは、どのインスタンスにも関連付けられていないことを意味します。一方、バインドされたメソッドは特定のインスタンスに関連付けられています。観察:

>>> A().fA
<bound method A.fA of <__main__.A object at 0x10f1d3d10>>

どちらの方法でも、メソッドはそれらを実装する関数をラップします。

>>> A.fA.im_func
<function fA at 0x10f1c2a28>

アドレスは以前に印刷されたものと同じであることに注意してください。

奇妙なことに、私はあなたが見ている動作を再現できません:

>>> A.fA.__dict__['x'] = 1
>>> A.fA.x
1

おそらく、この違いは python のバージョンが異なるためです。これが私のものです:

$ python
Python 2.7.2 (default, Jun 20 2012, 16:23:33) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 

PS: A.fA.x は、A.fA.im_func.x と同じように機能するようです。これには驚かされます...繰り返しますが、なぜこれを行うことを考えているのか、少し疑問です。通常、使用するの__dict__は、実装している場合のみです__getattr__( と混同しないでください__getattribute__)。

また、オブジェクト (特に基本型のオブジェクト) にアドホック属性を与えることが良い考えであることもまれです。通常実行可能な代替手段は、独自のマップを使用することです。

>>> def foo(): pass
... 
>>> my_x_values = {foo: 'X'}
>>> my_x_values[foo]
'X'

ただし、誰もがこれについて同意するわけではありません。この他の SO の質問を確認してください: Python 関数の属性 - 使用と悪用

于 2012-11-27T06:48:20.877 に答える