0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Python3で@staticmethod 付けなくてもクラスのmethodを直接呼べる

Last updated at Posted at 2020-07-16

Python3で@staticmethod付けなくてもクラスのmethodを直接呼べて驚いた話:scream:

通常classのmethodをコールするには、オブジェクトを生成してコールする。
もしくは、@classmethod@staticmethodを付けて直接コールするのどれかかと思います。

でも、タイトル通り直接呼べました。

環境

Python 3.8.2

@staticmethodつけないでコールする

簡単なサンプルを用意してみましょう。
下記コードでは、@staticmethodを付けていませんがfoo()メソッドが直接呼べちゃいます。

>>> class A:
...     def foo():         # @staticmethodつけない
...         print('Hello foo')
...
>>> A.foo()
Hello foo       <=== なぜか直接呼べる
>>> A().foo()
Traceback (most recent call last):   <=== オブジェクトからは呼べない 
  File "<stdin>", line 1, in <module>
TypeError: foo() takes 0 positional arguments but 1 was given
>>>

@staticmethodつけてコールする

では、今度はつけてみましょう。
@staticmethodを付けてるので直接呼べるのはもちろんですが、オブジェクトからも呼べちゃいます。

>>> class B:
...     @staticmethod      # @staticmethodつける
...     def foo():
...         print('Hello foo')
...
>>> B.foo()
Hello foo
>>> B().foo()
Hello foo       <=== オブジェクトからも呼べる
>>>

@staticmethodつける、つけないの違い

上記見てもらった通り、オブジェクトからも呼び出せるかどうかしかないように思えるのだけど、ちょっと分からないです。

つい最近まで、python3がこんな仕様だなんて知らなかった。
でも、@staticmethod付けた方が分かりやすいから、自分はこれからも付けます。

参考までに

では、Python2 ではどうだったか確認

環境

Python 2.7.16

確認

>>> class A:
...     def foo():               # @staticmethodつけない
...         print('Hello foo')
... 
>>> A.foo()
Traceback (most recent call last):   <=== 直接呼出しはダメ
  File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with A instance as first argument (got nothing instead)
>>> A().foo()
Traceback (most recent call last):    <=== オブジェクトからももちろんダメ
  File "<stdin>", line 1, in <module>
TypeError: foo() takes no arguments (1 given)
>>>
>>>
>>> class B:
...     @staticmethod             # @staticmethodつける
...     def foo():
...         print('Hello foo')
... 
>>> B.foo()
Hello foo           <=== @staticmethod つければ呼び出せる
>>> B().foo()
Hello foo
>>>

これを見るとPython2ではやっぱりダメですね。
でも、なんでPython3からOKになったんだろう?気になる。

参考にしたURL

https://stackoverflow.com/questions/43587044/do-we-really-need-staticmethod-decorator-in-python-to-declare-static-method
https://stackoverflow.com/questions/136097/difference-between-staticmethod-and-classmethod

0
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?