誰でも、Pythonで「メソッド」が何であるかを非常に簡単な言葉で説明してもらえますか?
初心者向けの多くのPythonチュートリアルでは、このWordは、Pythonのコンテキストでメソッドが何であるかを既に知っているかのように使用されています。もちろん、このWordの一般的な意味はよく知っていますが、この用語がPythonで何を意味するのかはわかりません。ですから、「Pythonian」メソッドとは何かを説明してください。
写真は数千語に値するので、いくつかの非常に単純なサンプルコードは非常に高く評価されます。
クラスのメンバーである関数です:
class C:
def my_method(self):
print "I am a C"
c = C()
c.my_method() # Prints "I am a C"
そのような単純な!
(別の種類のメソッドもあり、クラスと関数の関係を制御することができます。しかし、あなたはそれについて質問しているのではなく、基本だけを質問しているのではないかと推測しています。)
メソッドは、クラスインスタンスを最初のパラメーターとして受け取る関数です。メソッドはクラスのメンバーです。
class C:
def method(self, possibly, other, arguments):
pass # do something here
Pythonで具体的に何を意味するのかを知りたいので、バインドされたメソッドとバインドされていないメソッドを区別できます。 Pythonでは、すべての関数(およびメソッド)が渡され、「遊ぶ」ことができるオブジェクトです。したがって、非バインドメソッドとバインドメソッドの違いは次のとおりです。
1)バインドされたメソッド
# Create an instance of C and call method()
instance = C()
print instance.method # prints '<bound method C.method of <__main__.C instance at 0x00FC50F8>>'
instance.method(1, 2, 3) # normal method call
f = instance.method
f(1, 2, 3) # method call without using the variable 'instance' explicitly
バウンドメソッドは、クラスのインスタンスに属するメソッドです。この例では、instance.method
はinstance
というインスタンスにバインドされています。そのバインドされたメソッドが呼び出されるたびに、インスタンスは最初のパラメーターとして自動的に渡されます。これは慣例によりself
と呼ばれます.
2)非バインドメソッド
print C.method # prints '<unbound method C.method>'
instance = C()
C.method(instance, 1, 2, 3) # this call is the same as...
f = C.method
f(instance, 1, 2, 3) # ..this one...
instance.method(1, 2, 3) # and the same as calling the bound method as you would usually do
C.method
(インスタンス内ではなくクラス内のメソッド)にアクセスすると、バインドされていないメソッドが取得されます。メソッドを呼び出す場合、メソッドはnotインスタンスにバインドされているため、インスタンスを最初のパラメーターとして渡す必要があります。
その違いを知って、メソッドやメソッドをオブジェクトに渡すことができます。ユースケースの例として、コールバック関数を定義できるが、コールバック関数としてメソッドを提供したいAPIを想像してください。問題ありません。self.myCallbackMethod
をコールバックとして渡すだけで、インスタンスを最初の引数として自動的に呼び出されます。これは、C++のような静的言語では不可能です(またはトリックの場合のみ)。
あなたがポイントを得たことを願っています;)メソッドの基本について知っておくべきことはそれだけだと思います。 classmethod
およびstaticmethod
デコレーターについても読むことができますが、それは別のトピックです。
Pythonでは、メソッドは特定のオブジェクトで利用可能な関数ですオブジェクトのタイプのため。
たとえば、my_list = [1, 2, 3]
を作成すると、Pythonリストであるmy_list.append(4)
であるため、append
メソッドをmy_list
に適用できます。すべてのリストには、リストであるという理由だけでappend
メソッドがあります。
別の例として、my_string = 'some lowercase text'
を作成すると、Python文字列であるmy_string.upper()
であるため、upper
メソッドをmy_string
に適用できます。
リストにはupper
メソッドがなく、文字列にはappend
メソッドがありません。どうして?メソッドは特定のオブジェクトに対してのみ存在しますそのタイプのオブジェクトに対して明示的に定義されたであり、Pythonの開発者は(これまで)それらの特定のメソッドはそれらの特定のオブジェクトには必要ないと判断したためです。
メソッドを呼び出すための形式はobject_name.method_name()
で、メソッドの引数は括弧内にリストされます。このメソッドは、名前が付けられているオブジェクトに対して暗黙的に動作するため、オブジェクト自体が唯一の必要な引数であるため、一部のメソッドには引数が指定されていません。たとえば、my_string.upper()
にはリストされた引数がありません。これは、必要な引数がオブジェクト自体my_string
だけであるためです。
混乱の共通点の1つは、次の点に関するものです。
import math
math.sqrt(81)
sqrt
はmath
オブジェクトのメソッドですか? No。これは、sqrt
モジュールからmath
関数を呼び出す方法です。使用されている形式は、module_name.function_name()
ではなくobject_name.method_name()
です。一般に、2つの形式を(視覚的に)区別する唯一の方法は、残りのコードを調べて、ピリオドの前(math
、my_list
、my_string
)の部分を確認することですオブジェクトまたはモジュールとして定義されます。
申し訳ありませんが、私の意見では、RichieHindleはその方法を言うことについて完全に正しいです...
クラスのメンバーである関数です。
クラスのメンバーになる関数の例を次に示します。それ以降、クラスのメソッドとして動作します。 emptyクラスと、1つの引数を持つ通常の関数から始めましょう。
>>> class C:
... pass
...
>>> def func(self):
... print 'func called'
...
>>> func('whatever')
func called
次に、関数への参照であるC
クラスにメンバーを追加します。その後、クラスのインスタンスを作成し、クラス内で定義されているかのようにそのメソッドを呼び出すことができます。
>>> C.func = func
>>> o = C()
>>> o.func()
func called
メソッドを呼び出す別の方法も使用できます。
>>> C.func(o)
func called
o.func
は、クラスメソッドと同じように現れます:
>>> o.func
<bound method C.func of <__main__.C instance at 0x000000000229ACC8>>
そして、逆のアプローチを試すことができます。クラスを定義し、そのメソッドを関数として盗もう。
>>> class A:
... def func(self):
... print 'aaa'
...
>>> a = A()
>>> a.func
<bound method A.func of <__main__.A instance at 0x000000000229AD08>>
>>> a.func()
aaa
これまでのところ、同じように見えます。今、関数を盗む:
>>> afunc = A.func
>>> afunc(a)
aaa
真実は、メソッドが「何でも」引数を受け入れないということです:
>>> afunc('whatever')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method func() must be called with A instance as first
argument (got str instance instead)
私見、これはに対する引数ではありませんmethodはクラスのメンバーである関数です。
後で見つかったAlex Martelli's answer それは基本的に同じことを言っています。重複していると思われる場合は申し訳ありません:)
http://docs.python.org/2/tutorial/classes.html#method-objects
通常、メソッドはバインドされた直後に呼び出されます。
x.f()
MyClassの例では、これは文字列「hello world」を返します。ただし、すぐにメソッドを呼び出す必要はありません。x.fはメソッドオブジェクトであり、保存して後で呼び出すことができます。例えば:
xf = x.f while True: print xf()
hello worldを時間の終わりまで印刷し続けます。
メソッドが呼び出されるとどうなりますか? f()の関数定義で引数が指定されていても、上記の引数なしでx.f()が呼び出されたことにお気づきかもしれません。議論はどうなりましたか?本当にPythonは、引数を必要とする関数が引数なしで呼び出されたときに例外を発生させます-引数が実際に使用されていなくても...
実際、あなたは答えを推測したかもしれません:メソッドに関する特別なことは、オブジェクトが関数の最初の引数として渡されるということです。この例では、呼び出しx.f()はMyClass.f(x)とまったく同じです。一般に、n個の引数のリストでメソッドを呼び出すことは、最初の引数の前にメソッドのオブジェクトを挿入することにより作成される引数リストで対応する関数を呼び出すことと同等です。
それでもメソッドがどのように機能するか理解していない場合は、実装を見て問題を明確にすることができます。データ属性ではないインスタンス属性が参照されると、そのクラスが検索されます。名前が関数オブジェクトである有効なクラス属性を示す場合、メソッドオブジェクトは、抽象オブジェクトで一緒に見つかったインスタンスオブジェクトと関数オブジェクトをパック(ポインター)することによって作成されます。これはメソッドオブジェクトです。メソッドオブジェクトが引数リストで呼び出されると、インスタンスオブジェクトと引数リストから新しい引数リストが作成され、この新しい引数リストで関数オブジェクトが呼び出されます。
オブジェクトを名詞に似ていると考える場合、メソッドは動詞に似ています。オブジェクト(文字列またはリスト)の直後にメソッドを使用して、メソッドのアクションを適用します。