4

これは、私のマシンでプレイしたばかりの例です。

$ python
Python 2.7.4 (default, Apr 19 2013, 18:28:01) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
# just a test class 
>>> class A(object):
...   def hi(self):
...     print("hi")
... 
>>> a = A()
>>> a.hi()
hi
>>> def hello(self):
...   print("hello")
... 
>>> 
>>> hello(None)
hello
>>> 
>>> 
>>> 
>>> a.hi = hello
# now I would expect for hi to work the same way as before
# and it just prints hello instead of hi.
>>> a.hi()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: hello() takes exactly 1 argument (0 given)
>>> 
>>> def hello():
...   print("hello")
... 
# but instead this one works, which doesn't contain any
# reference to self
>>> a.hi = hello
>>> a.hi()
hello
>>> 
>>> 
>>> 
>>> 
>>> a.hello = hello
>>> a.hello()
hello

ここで何が起きてるの?関数がメソッドとして使用されている場合、関数がパラメーター self を取得しないのはなぜですか? 内部で自己への参照を取得するには、何をする必要がありますか?

4

2 に答える 2

8

あなたの場合、インスタンスを介して参照されるクラスのメソッドは、そのインスタンスにバインドされます。

In [3]: a.hi
Out[3]: <bound method A.hi of <__main__.A object at 0x218ab10>>

比較:

In [4]: A.hi
Out[4]: <unbound method A.hi>

したがって、おそらく必要な効果を得るには、次のようにします

In [5]: def hello(self):
   ...:     print "hello"
   ...:     

In [6]: A.hi = hello

In [7]: a.hi()
hello

注意 - これは のすべてのインスタンスに適用されますA。しかし、1 つのインスタンスだけでメソッドをオーバーライドしたい場合、本当に を渡す必要があるのselfでしょうか?

于 2013-06-18T08:33:50.760 に答える
3

これは、関数がクラス属性である場合に関数にアクセスする方法です。

クラス属性として追加された関数は、記述子としてアクセスされます。あなたがそうするなら、あなたはそれを見る

class A(object):
    pass

def f(*a): pass
A.f = f
print f
print A.f
print A().f

ここで、出力が得られます

<function f at 0x00F03D70>
<unbound method A.f>
<bound method A.f of <__main__.A object at 0x00F089D0>>

あなたが得られるのと同じ出力

print f
print f.__get__(None, A)
print f.__get__(A(), A)

それが記述子の仕組みだからです。

このすべて (記述子プロトコルを介した関数からメソッドへの変換) は、インスタンス属性では発生しません。

もしあなたがそうするなら

a = A()
a.f = f

thena.fは、メソッドとしてではなく、関数として読み戻されます。したがって、割り当てを行うときにこれを考慮する必要があります。

a.f = lambda: f(a)

関数に渡すためa

于 2013-06-18T08:35:18.330 に答える