@staticmethod
で修飾された関数と @classmethod
で修飾された関数の違いは何ですか?
多少のコード例が役立つでしょう:foo
、class_foo
およびstatic_foo
の呼び出しシグネチャの違いに注意してください。
class A(object):
def foo(self, x):
print "executing foo(%s, %s)" % (self, x)
@classmethod
def class_foo(cls, x):
print "executing class_foo(%s, %s)" % (cls, x)
@staticmethod
def static_foo(x):
print "executing static_foo(%s)" % x
a = A()
以下は、オブジェクトインスタンスがメソッドを呼び出す通常の方法です。オブジェクトインスタンスa
は、最初の引数として暗黙的に渡されます。
a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)
classmethods の場合、オブジェクトインスタンスのクラスは、self
の代わりに暗黙的に最初の引数として渡されます。
a.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
クラスを使ってclass_foo
を呼び出すこともできます。実際、何かをクラスメソッドとして定義した場合、おそらくそれはクラスインスタンスからではなくクラスからそれを呼び出すつもりだからでしょう。 A.foo(1)
はTypeErrorを送出しますが、A.class_foo(1)
はうまく動作します。
A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
人々がクラスメソッドのために見つけた1つの使用法は 継承可能な代替コンストラクタを作成することです 。
staticmethods の場合、self
(オブジェクトインスタンス)もcls
(クラス)も暗黙的に最初の引数として渡されません。インスタンスまたはクラスから呼び出すことができる点を除いて、これらは普通の関数のように動作します。
a.static_foo(1)
# executing static_foo(1)
A.static_foo('hi')
# executing static_foo(hi)
静的メソッドは、クラスと何らかの論理的な関係がある関数をグループ化するために使用されます。
foo
は単なる関数ですが、a.foo
を呼び出すときに関数を取得するだけではなく、オブジェクトインスタンスa
を関数の最初の引数としてバインドした「部分的に適用された」バージョンの関数を取得します。 foo
には2つの引数が必要ですが、a.foo
には1つの引数しか必要ありません。
a
はfoo
にバインドされています。これが、以下の「バインド」という用語の意味です。
print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
a.class_foo
では、a
はclass_foo
にバインドされず、クラスA
はclass_foo
にバインドされます。
print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>
ここでは、静的メソッドでは、メソッドであってもa.static_foo
は引数がバインドされていない適切な 'ole'関数を返すだけです。 static_foo
は1つの引数を期待し、a.static_foo
は1つの引数も期待します。
print(a.static_foo)
# <function static_foo at 0xb7d479cc>
そしてもちろん、代わりにクラスA
を使ってstatic_foo
を呼び出すときも同じことが起こります。
print(A.static_foo)
# <function static_foo at 0xb7d479cc>
staticmethod は、呼び出されたクラスやインスタンスについて何も知らないメソッドです。渡された引数を取得するだけです。暗黙の最初の引数はありません。 Pythonでは基本的に役に立ちません。静的メソッドの代わりにモジュール関数を使うことができます。
一方、 classmethod は、最初の引数として、呼び出されたクラス、または呼び出されたインスタンスのクラスを渡されるメソッドです。これは、メソッドをクラスのファクトリにしたい場合に役立ちます。最初の引数として呼び出された実際のクラスを取得するため、サブクラスが関係している場合でも常に正しいクラスをインスタンス化できます。たとえば、クラスメソッドであるdict.fromkeys()
が、サブクラスで呼び出されたときにサブクラスのインスタンスを返す方法を観察します。
>>> class DictSubclass(dict):
... def __repr__(self):
... return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
基本的に、@classmethod
は最初の引数が(クラスインスタンスではなく)呼び出し元のクラスであるメソッドを作成します。@staticmethod
は暗黙の引数を持ちません。
公式Pythonドキュメント:
インスタンスメソッドがインスタンスを受け取るのと同じように、クラスメソッドは暗黙の最初の引数としてクラスを受け取ります。クラスメソッドを宣言するには、次の慣用句を使用します。
class C: @classmethod def f(cls, arg1, arg2, ...): ...
@classmethod
フォームは関数 デコレータ です。詳細については 関数定義 の関数定義の説明を参照してください。クラス(
C.f()
など)またはインスタンス(C().f()
など)のどちらでも呼び出すことができます。インスタンスはそのクラス以外は無視されます。派生クラスに対してクラスメソッドが呼び出された場合、派生クラスオブジェクトは暗黙の最初の引数として渡されます。クラスメソッドは、C++またはJavaの静的メソッドとは異なります。必要な場合は、このセクションの
staticmethod()
を参照してください。
静的メソッドは、暗黙の最初の引数を受け取りません。静的メソッドを宣言するには、次の慣用句を使用します。
class C: @staticmethod def f(arg1, arg2, ...): ...
@staticmethod
フォームは関数 デコレータ です。詳細については 関数定義 の関数定義の説明を参照してください。クラス(
C.f()
など)またはインスタンス(C().f()
など)のどちらでも呼び出すことができます。インスタンスはそのクラス以外は無視されます。Pythonの静的メソッドは、JavaまたはC++のものと似ています。より高度な概念については、このセクションの
classmethod()
を参照してください。
ここ はこの質問に関する短い記事です。
@staticmethod関数はクラス内で定義された関数にすぎません。最初にクラスをインスタンス化せずに呼び出すことができます。その定義は継承によって不変です。
@classmethod関数もクラスをインスタンス化せずに呼び出すことができますが、その定義は継承を通じてParentクラスではなくSubクラスに従います。これは、@ classmethod関数の最初の引数が常にcls(class)でなければならないためです。
@staticmethod または @classmethod のどちらを使用するかを決定するには、メソッド内を調べる必要があります。 あなたのメソッドがあなたのクラスの他の変数/メソッドにアクセスする場合は@classmethod を使用してください。一方、あなたのメソッドがクラスの他のどの部分にも触れていない場合は@staticmethodを使います。
class Apple:
_counter = 0
@staticmethod
def about_Apple():
print('Apple is good for you.')
# note you can still access other member of the class
# but you have to use the class instance
# which is not very Nice, because you have repeat yourself
#
# For example:
# @staticmethod
# print('Number of apples have been juiced: %s' % Apple._counter)
#
# @classmethod
# print('Number of apples have been juiced: %s' % cls._counter)
#
# @classmethod is especially useful when you move your function to other class,
# you don't have to rename the class reference
@classmethod
def make_Apple_juice(cls, number_of_apples):
print('Make juice:')
for i in range(number_of_apples):
cls._juice_this(i)
@classmethod
def _juice_this(cls, Apple):
print('Juicing %d...' % Apple)
cls._counter += 1
Pythonの@staticmethodと@classmethodの違いは何ですか?
この擬似コードのようなPythonコードを見たことがあるかもしれません。このコードは、さまざまなメソッドタイプのシグネチャを示し、それぞれを説明するdocstringを提供します。
class Foo(object):
def a_normal_instance_method(self, arg_1, kwarg_2=None):
'''
Return a value that is a function of the instance with its
attributes, and other arguments such as arg_1 and kwarg2
'''
@staticmethod
def a_static_method(arg_0):
'''
Return a value that is a function of arg_0. It does not know the
instance or class it is called from.
'''
@classmethod
def a_class_method(cls, arg1):
'''
Return a value that is a function of the class and other arguments.
respects subclassing, it is called with the class it is called from.
'''
最初にa_normal_instance_method
について説明します。これは正確に「インスタンスメソッド」と呼ばれます。インスタンスメソッドが使用される場合、それは部分関数として使用されます(ソースコードで表示されるときにすべての値に対して定義される合計関数ではなく)。つまり、使用される場合、引数の最初は指定されたすべての属性を持つオブジェクト。オブジェクトのインスタンスがバインドされており、オブジェクトのインスタンスから呼び出す必要があります。通常、インスタンスのさまざまな属性にアクセスします。
たとえば、これは文字列のインスタンスです。
', '
この文字列でjoin
というインスタンスメソッドを使用して別の反復可能オブジェクトを結合する場合、反復可能リスト['a', 'b', 'c']
の関数であることに加えて、インスタンスの関数であることは明らかです。
>>> ', '.join(['a', 'b', 'c'])
'a, b, c'
インスタンスメソッドは、後で使用するためにドット付きルックアップを介してバインドできます。
たとえば、これはstr.join
メソッドを':'
インスタンスにバインドします。
>>> join_with_colons = ':'.join
後で、これを、最初の引数が既にバインドされている関数として使用できます。このように、インスタンスの部分関数のように機能します。
>>> join_with_colons('abcde')
'a:b:c:d:e'
>>> join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF'])
'FF:FF:FF:FF:FF:FF'
静的メソッドは、インスタンスを引数としてnotします。
モジュールレベルの機能に非常に似ています。
ただし、モジュールレベルの関数はモジュール内に存在し、使用する他の場所に特別にインポートする必要があります。
ただし、オブジェクトにアタッチされている場合は、インポートおよび継承も同様にオブジェクトに追従します。
静的メソッドの例は、Python 3のstring
モジュールから移動したstr.maketrans
です。これにより、str.translate
による消費に適した変換テーブルが作成されます。以下に示すように、文字列のインスタンスから使用するとかなり馬鹿げているように見えますが、string
モジュールから関数をインポートするのはかなり面倒で、str.maketrans
のようにクラスから呼び出すことができるのはいいことです
# demonstrate same function whether called from instance or not:
>>> ', '.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}
>>> str.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}
python 2では、ますます有用性の低い文字列モジュールからこの関数をインポートする必要があります。
>>> import string
>>> 'ABCDEFG'.translate(string.maketrans('ABC', 'abc'))
'abcDEFG'
クラスメソッドは、暗黙的な最初の引数を取るという点でインスタンスメソッドに似ていますが、インスタンスを取る代わりに、クラスを取ることになります。多くの場合、これらはセマンティック使用を改善するための代替コンストラクタとして使用され、継承をサポートします。
組み込みクラスメソッドの最も標準的な例は、dict.fromkeys
です。 dictの代替コンストラクターとして使用されます(キーが何であるかを知っていて、それらのデフォルト値が必要な場合に適しています)。
>>> dict.fromkeys(['a', 'b', 'c'])
{'c': None, 'b': None, 'a': None}
Dictをサブクラス化する場合、サブクラスのインスタンスを作成する同じコンストラクターを使用できます。
>>> class MyDict(dict): 'A dict subclass, use to demo classmethods'
>>> md = MyDict.fromkeys(['a', 'b', 'c'])
>>> md
{'a': None, 'c': None, 'b': None}
>>> type(md)
<class '__main__.MyDict'>
代替コンストラクタの他の同様の例については、 pandasソースコード を参照してください。また、 classmethod
の公式Pythonドキュメントも参照してください。および staticmethod
。
python 2.4で@decoratorsが追加されました。Python <2.4を使用している場合は、classmethod()およびstaticmethod()関数を使用できます。
たとえば、ファクトリメソッド(引数の種類に応じてクラスの異なる実装のインスタンスを返す関数)を作成する場合は、次のようにします。
class Cluster(object):
def _is_cluster_for(cls, name):
"""
see if this class is the cluster with this name
this is a classmethod
"""
return cls.__== name
_is_cluster_for = classmethod(_is_cluster_for)
#static method
def getCluster(name):
"""
static factory method, should be in Cluster class
returns a cluster object for the given name
"""
for cls in Cluster.__subclasses__():
if cls._is_cluster_for(name):
return cls()
getCluster = staticmethod(getCluster)
また、これはクラスメソッドと静的メソッドを使用する良い例です。静的メソッドはクラスClusterを内部的に使用するため、明らかにクラスに属します。クラスメソッドはクラスに関する情報のみを必要とし、オブジェクトのインスタンスは必要としません。
_is_cluster_for
メソッドをクラスメソッドにするもう1つの利点は、サブクラスがその実装を変更できるかどうかを判断できることです。これは、かなり一般的で、複数の種類のクラスタを処理できるためです。
私はもっと良い質問が「いつ@classmethodと@staticmethodを使うのですか?」だと思います。
@classmethodを使用すると、クラス定義に関連付けられているプライベートメンバーに簡単にアクセスできます。これは、シングルトン、つまり作成されたオブジェクトのインスタンス数を制御するファクトリクラスを作成するのに最適な方法です。
@staticmethodを使用するとパフォーマンスが大幅に向上しますが、クラス内で静的メソッドを生産的に使用することは、クラス外のスタンドアロン関数としては実現できませんでした。
静的メソッド:
静的メソッドの利点:
各メソッドを特別にインポートする必要がないため、モジュールレベルの関数に対してインポートする方が便利
@staticmethod
def some_static_method(*args, **kwds):
pass
クラスメソッド:
これらはclassmethod組み込み関数で作成されています。
@classmethod
def some_class_method(cls, *args, **kwds):
pass
私はC++、それからJavaそしてそれからPythonでプログラミング言語を学び始めました、それで私がそれぞれの単純な用法を理解するまで、この質問は私にも多くを悩ませました。
クラスメソッド: JavaやC++とは異なりPythonには、コンストラクタのオーバーロードはありません。そしてこれを達成するためにはclassmethod
を使うことができます。次の例でこれを説明します
first_name
とlast_name
の2つの引数を取り、Person
のインスタンスを作成するPerson
クラスがあるとしましょう。
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
さて、もしfirst_name
だけの単一の名前だけを使ってクラスを作成する必要があるという要求があるなら、 はできません Pythonではこのようなことはできません。
オブジェクト(インスタンス)を作成しようとすると、これはエラーになります。
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def __init__(self, first_name):
self.first_name = first_name
ただし、@classmethod
を使用して以下のように同じことを実現できます。
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@classmethod
def get_person(cls, first_name):
return cls(first_name, "")
静的メソッド: これはどちらかといえば簡単です。インスタンスやクラスに縛られることはなく、単にクラス名を使って呼び出すことができます。
それで、上の例でfirst_name
が20文字を超えてはならないという検証が必要だとしましょう、あなたは単にこれをすることができます。
@staticmethod
def validate_name(name):
return len(name) <= 20
class name
を使って呼び出すこともできます
Person.validate_name("Gaurang Shah")
@staticmethod
は、メソッド記述子としてデフォルトの関数を無効にするだけです。 classmethodは、最初の引数として所有クラスへの参照を渡すコンテナ呼び出し可能オブジェクトに関数をラップします。
>>> class C(object):
... pass
...
>>> def f():
... pass
...
>>> staticmethod(f).__get__(None, C)
<function f at 0x5c1cf0>
>>> classmethod(f).__get__(None, C)
<bound method type.f of <class '__main__.C'>>
実際のところ、classmethod
はランタイムオーバーヘッドがありますが、所有クラスへのアクセスを可能にします。あるいは、メタクラスを使用して、そのメタクラスにクラスメソッドを配置することをお勧めします。
>>> class CMeta(type):
... def foo(cls):
... print cls
...
>>> class C(object):
... __metaclass__ = CMeta
...
>>> C.foo()
<class '__main__.C'>
Pythonで静的メソッド、クラスメソッド、抽象メソッドを使用する方法についての最も信頼のおけるガイド は、このトピックへの良いリンクの1つです。
@staticmethod
functionはクラス内で定義された関数にすぎません。最初にクラスをインスタンス化せずに呼び出すことができます。その定義は継承によって不変です。
@classmethod
関数もクラスをインスタンス化せずに呼び出すことができますが、その定義は継承を通じてParentクラスではなくSubクラスに従います。継承はサブクラスでオーバーライドできます。これは、@classmethod
関数の最初の引数が常にcls(class)でなければならないためです。
最初に@classmethodと@staticmethodで装飾されたメソッドの類似性を教えてください。
類似性: 両方とも、クラスの instance ではなく Class 自体で呼び出すことができます。つまり、両方ともある意味では Classのメソッド です。
違い: クラスメソッドはクラス自身を最初の引数として受け取りますが、静的メソッドは受け取りません。
したがって、静的メソッドは、ある意味ではClass自体にバインドされておらず、関連する機能を持っているからといってそこに留まっているだけです。
>>> class Klaus:
@classmethod
def classmthd(*args):
return args
@staticmethod
def staticmthd(*args):
return args
# 1. Call classmethod without any arg
>>> Klaus.classmthd()
(__main__.Klaus,) # the class gets passed as the first argument
# 2. Call classmethod with 1 arg
>>> Klaus.classmthd('chumma')
(__main__.Klaus, 'chumma')
# 3. Call staticmethod without any arg
>>> Klaus.staticmthd()
()
# 4. Call staticmethod with 1 arg
>>> Klaus.staticmthd('chumma')
('chumma',)
Staticmethodとclassmethodに関するもう1つの考慮事項は、継承です。次のようなクラスがあるとします。
class Foo(object):
@staticmethod
def bar():
return "In Foo"
そして、子クラスのbar()
をオーバーライドします。
class Foo2(Foo):
@staticmethod
def bar():
return "In Foo2"
これは機能しますが、現在は子クラス(Foo2
)のbar()
実装はそのクラスに固有のものを利用できなくなっています。たとえば、Foo2
にmagic()
のFoo2
実装で使用したいbar()
というメソッドがあるとします。
class Foo2(Foo):
@staticmethod
def bar():
return "In Foo2"
@staticmethod
def magic():
return "Something useful you'd like to use in bar, but now can't"
ここでの回避策はFoo2.magic()
の中でbar()
を呼び出すことですが、その後繰り返します(Foo2
の名前が変わった場合は、そのbar()
メソッドを更新することを忘れないでください)。
Foo
で行われた決定は派生クラスの共通コードをリファクタリングする能力に影響を及ぼしているため(つまり、拡張に対してオープンではありません)、私には、これは open/closedの原則 のわずかな違反です。 bar()
がclassmethod
であれば、問題ないでしょう。
class Foo(object):
@classmethod
def bar(cls):
return "In Foo"
class Foo2(Foo):
@classmethod
def bar(cls):
return "In Foo2 " + cls.magic()
@classmethod
def magic(cls):
return "MAGIC"
print Foo2().bar()
与えます:In Foo2 MAGIC
例を使って基本的な違いを説明します。
class A(object):
x = 0
def say_hi(self):
pass
@staticmethod
def say_hi_static():
pass
@classmethod
def say_hi_class(cls):
pass
def run_self(self):
self.x += 1
print self.x # outputs 1
self.say_hi()
self.say_hi_static()
self.say_hi_class()
@staticmethod
def run_static():
print A.x # outputs 0
# A.say_hi() # wrong
A.say_hi_static()
A.say_hi_class()
@classmethod
def run_class(cls):
print cls.x # outputs 0
# cls.say_hi() # wrong
cls.say_hi_static()
cls.say_hi_class()
1 - 初期化せずに静的メソッドとクラスメソッドを直接呼び出すことができます
# A.run_self() # wrong
A.run_static()
A.run_class()
2 - 静的メソッドは自己メソッドを呼び出すことはできませんが、他の静的メソッドとクラスメソッドを呼び出すことができます
3-静的メソッドはクラスに属し、オブジェクトをまったく使用しません。
4-クラスメソッドはオブジェクトではなくクラスにバインドされます。
@classmethod:複数のユーザによるレコードの更新のように、そのクラスで作成されたすべてのインスタンスへの共有グローバルアクセスを作成するために使用することができます。 )
@staticメソッド:に関連付けられているクラスやインスタンスとは関係ありません...しかし読みやすくするためにstaticメソッドを使うことができます
私の貢献は、@classmethod
、@staticmethod
、およびインスタンスメソッドの違い(インスタンスが間接的に@staticmethod
を呼び出すことができる方法を含む)の違いを示しています。しかし、インスタンスから間接的に@staticmethod
を呼び出す代わりに、それを非公開にすることはより「Pythonic」になるかもしれません。プライベートメソッドから何かを取得することはここでは説明されていませんが、それは基本的に同じ概念です。
#!python3
from os import system
system('cls')
# % % % % % % % % % % % % % % % % % % % %
class DemoClass(object):
# instance methods need a class instance and
# can access the instance through 'self'
def instance_method_1(self):
return 'called from inside the instance_method_1()'
def instance_method_2(self):
# an instance outside the class indirectly calls the static_method
return self.static_method() + ' via instance_method_2()'
# class methods don't need a class instance, they can't access the
# instance (self) but they have access to the class itself via 'cls'
@classmethod
def class_method(cls):
return 'called from inside the class_method()'
# static methods don't have access to 'cls' or 'self', they work like
# regular functions but belong to the class' namespace
@staticmethod
def static_method():
return 'called from inside the static_method()'
# % % % % % % % % % % % % % % % % % % % %
# works even if the class hasn't been instantiated
print(DemoClass.class_method() + '\n')
''' called from inside the class_method() '''
# works even if the class hasn't been instantiated
print(DemoClass.static_method() + '\n')
''' called from inside the static_method() '''
# % % % % % % % % % % % % % % % % % % % %
# >>>>> all methods types can be called on a class instance <<<<<
# instantiate the class
democlassObj = DemoClass()
# call instance_method_1()
print(democlassObj.instance_method_1() + '\n')
''' called from inside the instance_method_1() '''
# # indirectly call static_method through instance_method_2(), there's really no use
# for this since a @staticmethod can be called whether the class has been
# instantiated or not
print(democlassObj.instance_method_2() + '\n')
''' called from inside the static_method() via instance_method_2() '''
# call class_method()
print(democlassObj.class_method() + '\n')
''' called from inside the class_method() '''
# call static_method()
print(democlassObj.static_method())
''' called from inside the static_method() '''
"""
# whether the class is instantiated or not, this doesn't work
print(DemoClass.instance_method_1() + '\n')
'''
TypeError: TypeError: unbound method instancemethod() must be called with
DemoClass instance as first argument (got nothing instead)
'''
"""
@staticmethod 文字通り を分析してさまざまな洞察を得てください。
クラスの通常のメソッドは暗黙の dynamic メソッドで、インスタンスを最初の引数として取ります。
対照的に、静的メソッドはインスタンスを最初の引数として受け取らないので、 'static' と呼ばれます。
静的メソッドは確かにそのような通常の関数で、クラス定義外のものと同じです。
それは、それが適用される場所に近づくために、幸いにもクラスに分類されます。または、スクロールして見つけることができます。
名前が示すように、クラスメソッドはオブジェクトではなくクラスに変更を加えるために使用されます。クラスを変更するには、クラスを更新する方法であるため、クラス属性を変更します(オブジェクト属性ではありません)。これが、クラスメソッドがクラス(通常は 'cls'で表される)を最初の引数として受け取る理由です。
class A(object):
m=54
@classmethod
def class_method(cls):
print "m is %d" % cls.m
一方、静的メソッドは、クラスにバインドされていない機能、つまりクラス変数を読み書きしない機能を実行するために使用されます。したがって、静的メソッドはクラスを引数として取りません。それらは、クラスがクラスの目的に直接関係しない機能を実行できるように使用されます。
class X(object):
m=54 #will not be referenced
@staticmethod
def static_method():
print "Referencing/calling a variable or function outside this class. E.g. Some global variable/function."
次の点の違いを検討するとよいでしょう。
Class A:
def foo(): # no self parameter, no decorator
pass
そして
Class B:
@staticmethod
def foo(): # no self parameter
pass
これはpython2とpython3の間で変わりました:
python2:
>>> A.foo()
TypeError
>>> A().foo()
TypeError
>>> B.foo()
>>> B().foo()
python3:
>>> A.foo()
>>> A().foo()
TypeError
>>> B.foo()
>>> B().foo()
そのため、クラスから直接呼び出されるメソッドにのみ@staticmethod
を使用することはpython3ではオプションになりました。クラスとインスタンスの両方からそれらを呼び出したい場合は、@staticmethod
デコレータを使用する必要があります。
他のケースは、未解決の答えで十分にカバーされています。
オブジェクトのメソッドが呼び出されると、自動的に最初の引数として追加の引数self
が与えられます。つまり、方法
def f(self, x, y)
2つの引数で呼び出さなければなりません。 self
は自動的に渡され、それは オブジェクトそのもの です。
方法が装飾されている場合
@classmethod
def f(cls, x, y)
自動的に提供される引数 は self
ではなくself
のクラスです。
方法が装飾されている場合
@staticmethod
def f(x, y)
メソッドが与えられていない 自動引数がまったくない。それが呼び出されるパラメータのみが与えられます。
classmethod
は主に代替コンストラクタに使用されます。staticmethod
はオブジェクトの状態を使用しません。それはクラスの外部の関数かもしれません。同様の機能を持つ関数をグループ化するためだけにクラス内に配置されます(たとえば、JavaのMath
クラスの静的メソッドのように)class Point
def __init__(self, x, y):
self.x = x
self.y = y
@classmethod
def frompolar(cls, radius, angle):
"""The `cls` argument is the `Point` class itself"""
return cls(radius * cos(angle), radius * sin(angle))
@staticmethod
def angle(x, y):
return atan(y, x)
p1 = Point(3, 2)
p2 = Point.frompolar(3, pi/4)
angle = Point.angle(3, 2)