web-dev-qa-db-ja.com

Pythonの「クラスメソッド」と「インスタンスメソッド」とは何ですか?

質問(これ自体は無関係な質問自体)に関連するチャットでの議論があり、Pythonはまったく知らない可能性があります。

私の考えでは、用語は言語によって異なりますが、一般的に関数は次のように分類されます。

  • 【無料】機能
  • 静的メソッド/静的メンバー関数
  • 非静的メソッド/非静的メンバー関数

どうやらPython=には、上記のカテゴリに当てはまらない別の種類の関数があります。1つはメソッドですが、「そのクラスを知りません」。

Pythonの「クラスメソッド」と「インスタンスメソッド」とは何ですか?

短い答え

  • インスタンスメソッドはそのインスタンスを知っています(そしてそれから、そのクラス)
  • クラスメソッドはそのクラスを知っています
  • 静的メソッドはそのクラスまたはインスタンスを認識していません

長い答え

クラスメソッド

クラスメソッドは、全体としてクラスに属するメソッドです。インスタンスは必要ありません。代わりに、クラスは最初の引数として自動的に送信されます。クラスメソッドは、@classmethodデコレータを使用して宣言されます。

例えば:

class Foo(object):
    @classmethod
    def hello(cls):
        print("hello from %s" % cls.__name__)
Foo.hello()
-> "Hello from Foo"
Foo().hello()
-> "Hello from Foo"

インスタンスメソッド

一方、インスタンスメソッドrequires呼び出すためのインスタンスであり、デコレータは必要ありません。これは、最も一般的なタイプのメソッドです。

class Foo(object):
    def hello(self):
        print("hello from %s" % self.__class__.__name__)
Foo.hello()
-> TypeError: hello() missing 1 required positional argument: 'self'

(注:上記はpython3の場合です。python2の場合は、少し異なるエラーが発生します)

静的メソッド

静的メソッドはクラスメソッドに似ていますが、クラスオブジェクトを自動パラメーターとして取得しません。 @staticmethodデコレータを使用して作成されます。

class Foo(object):
    @staticmethod
    def hello(cls):
        print("hello from %s" % cls.__name__)

Foo.hello()
-> TypeError: hello() missing 1 required positional argument: 'cls'

ドキュメントのリンク

関連するpython3ドキュメントへのリンクは次のとおりです。

データモデルのドキュメント は、クラスメソッドと静的メソッドの違いについて述べています。

静的メソッドオブジェクト静的メソッドオブジェクトは、上記のメソッドオブジェクトへの関数オブジェクトの変換を無効にする方法を提供します。静的メソッドオブジェクトは、他のオブジェクト(通常はユーザー定義のメソッドオブジェクト)のラッパーです。静的メソッドオブジェクトがクラスまたはクラスインスタンスから取得される場合、実際に返されるオブジェクトはラップされたオブジェクトであり、これ以上の変換は行われません。静的メソッドオブジェクト自体は呼び出し可能ではありませんが、通常、ラップするオブジェクトは呼び出し可能です。静的メソッドオブジェクトは、組み込みのstaticmethod()コンストラクターによって作成されます。

クラスメソッドオブジェクトクラスメソッドオブジェクトは、静的メソッドオブジェクトと同様に、別のオブジェクトのラッパーであり、そのオブジェクトがクラスから取得される方法を変更しますおよびクラスインスタンス。このような取得時のクラスメソッドオブジェクトの動作については、上記の「ユーザー定義メソッド」で説明しています。クラスメソッドオブジェクトは、組み込みのclassmethod()コンストラクターによって作成されます。

関連する質問

50
Bryan Oakley

Pythonの「クラスメソッド」と「インスタンスメソッド」とは何ですか?

  • 「インスタンスメソッド」は、インスタンスに含まれている情報を使用して、返す値(または実行する副作用)を決定します。これらは非常に一般的です。

  • 「クラスメソッド」は、クラス(およびそのクラスのインスタンスではない)に関する情報を使用して、その機能に影響を与えます(通常、これらは代替インスタンスとして新しいインスタンスを作成するために使用されるため、あまり一般的ではありません)。

  • 「静的メソッド」は、クラスまたはインスタンスに関する情報を使用して、その機能を計算しません。便宜上、通常はクラス内にあります。 (そのため、これらもあまり一般的ではありません。)

Xの関数

数学クラスを覚えてください、「yはxの関数、f(x)?」それをコードに適用してみましょう:

y = function(x)

上記は、xが変更される可能性があるため、yが変更されるとxが変更される可能性があることを意味しています。これは、「yxの関数」であると私たちが言うときの意味です。

y1の場合、zはどうなりますか? 2'FooBarBaz'

yzの関数ではないため、zは何でもかまいませんが、functionが純粋な関数であると仮定すると、関数の結果に影響を与えることはありません。 (グローバル変数としてzにアクセスする場合、それは純粋な関数ではありません-これは関数の純粋性が意味するものです。)

以下の説明を読むときは、上記のことを覚えておいてください。

インスタンスメソッド

インスタンスメソッドは、a関数ofインスタンスである関数です。関数はインスタンスを引数として暗黙的に受け入れ、インスタンスは関数の出力を決定するために関数によって使用されます。

インスタンスメソッドの組み込み例はstr.lowerです。

>>> 'ABC'.lower()
'abc'

str.lowerは文字列のインスタンスで呼び出され、インスタンスに含まれる情報を使用して、どの新しい文字列を返すかを判断します。

クラスメソッド:

Pythonでは、すべてがオブジェクトであることに注意してください。つまり、クラスはオブジェクトであり、引数として関数に渡すことができます。

クラスメソッドは、が関数of the classである関数です。クラスを引数として受け入れます。

組み込みの例はdict.fromkeysです。

>>> dict.fromkeys('ABC')
{'C': None, 'B': None, 'A': None}

関数は暗黙的に独自のクラスを認識し、関数はクラスを使用して関数の出力に影響を与え、反復可能クラスからそのクラスの新しいクラスを作成します。 OrderedDictは、同じメソッドを使用するときにこれを示します。

>>> from collections import OrderedDict
>>> OrderedDict.fromkeys('ABC')
OrderedDict([('A', None), ('B', None), ('C', None)])

クラスメソッドは、クラス(およびそのクラスのインスタンスではない)に関する情報を使用して、返されるクラスのタイプに影響を与えます。

静的メソッド

「そのクラスを知らない」メソッドについて言及している-これはPythonの静的メソッドです。クラスオブジェクトの便宜のために添付されているだけです。オプションで、別のモジュールの別の関数にすることもできますが、その呼び出し署名は同じです。

静的メソッドは、クラスでもオブジェクトでもない関数です。

静的メソッドの組み込みの例は、str = maketrans from Python 3。

>>> str.maketrans('abc', 'bca')
{97: 98, 98: 99, 99: 97}

いくつかの引数を指定すると、そのクラスの関数ではない辞書が作成されます。

strは常にグローバル名前空間で使用できるので便利であり、translate関数で簡単に使用できます。

>>> 'abracadabra'.translate(str.maketrans('abc', 'bca'))
'bcrbabdbcrb'

Python 2では、stringモジュールからアクセスする必要があります。

>>> 'abracadabra'.translate(str.maketrans('abc', 'bca'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'str' has no attribute 'maketrans'
>>> import string
>>> 'abracadabra'.translate(string.maketrans('abc', 'bca'))
'bcrbabdbcrb'

class AClass(object):
    """In Python, a class may have several types of methods: 
    instance methods, class methods, and static methods
    """

    def an_instance_method(self, x, y, z=None):
        """this is a function of the instance of the object
        self is the object's instance
        """
        return self.a_class_method(x, y)

    @classmethod
    def a_class_method(cls, x, y, z=None):
        """this is a function of the class of the object
        cls is the object's class
        """
        return cls.a_static_method(x, y, z=z)

    @staticmethod
    def a_static_method(x, y, z=None):
        """this is neither a function of the instance or class to 
        which it is attached
        """
        return x, y, z

インスタンス化しましょう:

>>> instance = AClass()

これで、インスタンスはすべてのメソッドを呼び出すことができます。

>>> instance.an_instance_method('x', 'y')
('x', 'y', None)
>>> instance.a_static_method('x', 'y')
('x', 'y', None)
>>> instance.a_class_method('x', 'y')
('x', 'y', None)

しかし、クラスは通常、インスタンスメソッドを呼び出すことを意図していませんが、他のクラスを呼び出すことが期待されています。

>>> AClass.a_class_method('x', 'y')
('x', 'y', None)
>>> AClass.a_static_method('x', 'y')
('x', 'y', None)
>>> AClass.an_instance_method('x', 'y')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: an_instance_method() missing 1 required positional argument: 'y'

インスタンスメソッドを呼び出すには、インスタンスを明示的に渡す必要があります。

>>> AClass.an_instance_method(instance, 'x', 'y')
('x', 'y', None)
8
Aaron Hall
  • 「インスタンスメソッド」は、インスタンスオブジェクトを最初のパラメータとして渡すメソッドで、慣例によりselfと呼ばれます。これがデフォルトです。

  • 「静的メソッド」とは、最初のselfパラメータのないメソッドです。これは @ staticmethodデコレータ で実装されています。

  • 「クラスメソッド」は、初期パラメータがインスタンスオブジェクトではなくクラスオブジェクトであるメソッドです( Python docs のこの部分を参照)==クラスオブジェクト "is)、これは慣例的にclsと呼ばれます。これは @ classmethodデコレータ で実装されます。

C/C++/etcでの「静的メソッド」という用語の一般的な使用法は、Python "static"とPython "class"メソッドの両方に当てはまります。これらのタイプのメソッドにはインスタンスへの参照がありません。C/ C++/etcでは、メソッドは通常、クラスのインスタンス以外のすべてのメンバー/メソッドに暗黙的にアクセスできます。そのため、この区別はPython/Rubyなどの言語にのみ存在します/等。

4
Ixrec