質問(これ自体は無関係な質問自体)に関連するチャットでの議論があり、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()コンストラクターによって作成されます。
Pythonの「クラスメソッド」と「インスタンスメソッド」とは何ですか?
「インスタンスメソッド」は、インスタンスに含まれている情報を使用して、返す値(または実行する副作用)を決定します。これらは非常に一般的です。
「クラスメソッド」は、クラス(およびそのクラスのインスタンスではない)に関する情報を使用して、その機能に影響を与えます(通常、これらは代替インスタンスとして新しいインスタンスを作成するために使用されるため、あまり一般的ではありません)。
「静的メソッド」は、クラスまたはインスタンスに関する情報を使用して、その機能を計算しません。便宜上、通常はクラス内にあります。 (そのため、これらもあまり一般的ではありません。)
数学クラスを覚えてください、「yはxの関数、f(x)
?」それをコードに適用してみましょう:
y = function(x)
上記は、x
が変更される可能性があるため、y
が変更されるとx
が変更される可能性があることを意味しています。これは、「y
はx
の関数」であると私たちが言うときの意味です。
y
が1
の場合、z
はどうなりますか? 2
? 'FooBarBaz'
?
y
はz
の関数ではないため、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)
「インスタンスメソッド」は、インスタンスオブジェクトを最初のパラメータとして渡すメソッドで、慣例によりself
と呼ばれます。これがデフォルトです。
「静的メソッド」とは、最初のself
パラメータのないメソッドです。これは @ staticmethodデコレータ で実装されています。
「クラスメソッド」は、初期パラメータがインスタンスオブジェクトではなくクラスオブジェクトであるメソッドです( Python docs のこの部分を参照)==クラスオブジェクト "is)、これは慣例的にcls
と呼ばれます。これは @ classmethodデコレータ で実装されます。
C/C++/etcでの「静的メソッド」という用語の一般的な使用法は、Python "static"とPython "class"メソッドの両方に当てはまります。これらのタイプのメソッドにはインスタンスへの参照がありません。C/ C++/etcでは、メソッドは通常、クラスのインスタンス以外のすべてのメンバー/メソッドに暗黙的にアクセスできます。そのため、この区別はPython/Rubyなどの言語にのみ存在します/等。