なぜpycharmはメソッドを静的に変更することを提案するのですか?


153

新しいpycharmリリース(3.1.3コミュニティエディション)では、現在のオブジェクトの状態で機能しないメソッドをstaticに変換することを提案しています。

ここに画像の説明を入力してください

その実際的な理由は何ですか?ある種のマイクロパフォーマンス(またはメモリ)最適化?


3
「もっと...」をクリックしましたか?selfメソッド内のどこかを参照していますか?(本当にPyCharmのデザイナーがなぜこのように設計したのかという質問である場合は、SOではなく質問する必要があります...)
Wooble

7
@Wooble:return 1メソッドの単一行の実装があります。「その他」には有用なものが含まれていません
zerkms 2014年

回答:


188

PyCharm は、静的メソッドが必要であると考えているが、それが静的であることを宣言するのを忘れている(@staticmethodデコレータを使用)。

PyCharmはこれを提案します。メソッドがその本体で使用 しないため、クラスインスタンスをself実際に変更しないためです。したがって、メソッドは静的、つまりクラスインスタンスを渡さずに、またはクラスインスタンスを作成しなくても呼び出すことができます。


4
多くの人がこのフレーバーレスポンスで答えました。ただし、それが静的メソッドではないことが確実にわかっている場合は、「thnot NotImplementedError」を含め、完了しないと使用できないことを確認します。
リチャードグリーン

1
静的メソッドも状態も変更したくないという点で、PyCharmの警告が正当化されない場合があります。一方、メソッドがまだ実装されていない場合は、常にを上げることをお勧めしNotImplementedErrorます。
jolvi 2016年

3
私のデフォルトの実装が定数を返す場合がありますが、私のサブクラスはに応じて値を返すことができselfます。この場合、警告は無視でき、私はそれをでマークしてい# noinspection PyMethodMayBeStaticます。IntelliJ IDEAがこの警告のコンテキストメニューにこの無効化コメントを追加する機能を提供していないのは気の毒です。
Alfe

PyCharmの設定で、このPyCharm検査の重大度を「警告」から「強調表示なし、修正のみ」に変更することをお勧めします。(私にとって多くの誤
検知が発生

50

@ jolvi、@ ArundasR、およびその他と同意し、警告はを使用しないメンバー関数で発生しますself

PyCharmが間違っていることが確かであり、関数がであってはならないこと@staticmethod、およびゼロの警告を評価する場合、これを2つの異なる方法で回避することができます。

回避策#1

def bar(self):
    self.is_not_used()
    doing_something_without_self()

def is_not_used(self):
    pass

回避策#2 [ @DavidPärssonに感謝 ]

# noinspection PyMethodMayBeStatic
def bar(self):
    doing_something_without_self()

このために使用したアプリケーション(@staticmethodを使用できなかった理由)は、プロトコルサブタイプフィールドに応答するためのハンドラー関数のテーブルを作成することでした。すべてのハンドラーは、同じ形式(静的または非静的)である必要があります。しかし、インスタンスで何もしなかった人もいます。これらを静的にすると、「TypeError: 'staticmethod' object is not callable」と表示されます。

OPの状況をサポートするために、できる限りstaticmethodを追加するよう提案することは、コードをより制限するよりも後で制限を少なくする方が簡単であるという原則に反します。メソッドを静的にすると、制限が緩和され、 instance.f()の代わりにclass.f()を呼び出します。

この警告が存在する理由について推測:

  • これは、staticmethodアドバタイズ。これにより、開発者は意図したことを認識できます。
  • @JohnWorrallが指摘しているように、誤ってselfが関数から除外されたときに、注意が向けられます。
  • オブジェクトモデルを再考するのは手がかりです。関数がこのクラスに属しいない可能性があります。

1
「メソッドを静的にすることで、制限が緩和されます」---まったくそうではありません。例:ポリモーフィックメソッド
zerkms '

最後のポイントは繰り返しますが、「それが明らかに関数であるのに、なぜそれをメソッドにするのですか?」インスタンスを本当に必要とするものは、いくつかの側面を扱う構造的なものとは別にしてください。その後、簡単に別のモジュールに分割できます。
dhill、2015年

@dhillルールは、妥当な例外を考える日までは美しいものです。1つ、コールバックのリストについて説明しました。
ボブスタイン

7
# noinspection PyMethodMayBeStaticメソッドまたはクラスの上に追加すると警告が抑制され、空のメソッドを呼び出すよりも良いと思います。
デビッドパーソン2017年

1
@Talha:selfPython3ではまったく削除されていません。
Junuxx

12

この警告の理由はPycharmの設定にあると思います。選択のチェックを外すことができます方法は静的-エディター->インスペクション


12
私の質問は、なぜそのような検査が存在するのかということでした。オフにできることを理解しています。すみません、答えではありません。
zerkms 2016年

8

私はここで与えられた答えに同意します(メソッドは使用しないためself、で装飾できます@staticmethod)。

メソッドをクラス内の静的メソッドではなくトップレベルの関数に移動したい場合があることを付け加えておきます。詳細については、この質問と承認された回答を参照してください:python-静的メソッドまたはトップレベル関数を使用する必要があります

メソッドをトップレベルの関数に移動すると、PyCharm警告も修正されます。


本当に役立つ答え-おそらくPyCharmは警告の名前を「メソッドが静的またはトップレベルの関数である可能性がある」に変更する必要があります。メソッドをリファクタリングするとき、pycharmはself、パラメータではない場合でも、静的メソッドではなくトップレベルの関数を作成します。
スザナ

@tloデコレータについて言及するための+1。私は使用しないメソッドを含むクラスを持っているselfため、トップレベルである可能性がありますが、このメソッドが何をするかを見るとこれは論理的に感じられません-トップレベルとしては、グローバルメソッドのように見えます実際、そのクラスから作成されたインスタンスの小さなヘルパーメソッド。したがって、コードを論理的に整理するには、デコレータが最適なソリューションです。
カシミール

7

クラスメソッドを静的メソッドとして定義することの次の利点を想像できます。

  • クラス名を使用してメソッドを呼び出すことができ、インスタンス化する必要はありません。

残りの利点は、もし存在するとしても、おそらくわずかです。

  • 少し速く動くかもしれません
  • メモリを少し節約する

うん。しかし、問題は-静的メソッドとして使用していないことです。そうでなければ、それはすでに静的です。だからPyCharmは正当な理由なしにそれを行うようにアドバイスします(?)。「残りの利点は、もし存在するとしても、おそらくわずかなものです」---そうです。しかし、もしそうなら、それはPyCharmからのばかげたアドバイスです
zerkms

1
@zerkmsこれは、いくつかの魅力的なインスタンスでどのように機能するかです:-)
Jan Vlcinsky

1
静的メソッドは、優れたソフトウェアを構築するための敵です。彼らは多くの原則を無効にしているので、bit高速で実行することは重要ではありません(どちらの場合もRAMで実行するので高速なので)bunch。また、最初の考えにも注意してください。これは手続き型の動作であり、オブジェクト指向の動作ではありません。
AmirHossein 2017

4

あなたはを参照していなかったのでself中にbarメソッド本体あなたがあれば、PyCharmを求めているかもしれない作りたいと思っているbar静的に。Javaなどの他のプログラミング言語では、静的メソッドを宣言する明らかな理由があります。Pythonでは、静的メソッド(AFIK)の唯一の真の利点は、クラスのインスタンスなしでそれを呼び出すことができることです。ただし、それが唯一の理由である場合は、トップレベルの関数を使用するほうがよいでしょう- ここで注記します

要するに、なぜそれが存在するのか私は100%確信がありません。彼らはおそらく今後のリリースでそれを削除するだろうと思います。


3

このエラーメッセージは、テスト用のサンプルプレーヤーを使用して誤って関数を記述したことに気付いていなかったため、役に立ちました。

my_player.attributes[item] 

正しい方法の代わりに

self.attributes[item]

1

少し面倒かもしれませんが、にアクセスする必要がない場合もありますselfが、メソッドをクラスに保持し、静的にしない方がよいでしょう。または、見苦しいデコレータの追加を避けたいだけです。ここでは、そのような状況に対する潜在的な回避策をいくつか示します。

メソッドに副作用しかなく、何が返されるかを気にしない場合:

def bar(self):
    doing_something_without_self()
    return self

戻り値が必要な場合:

def bar(self):
    result = doing_something_without_self()
    if self:
        return result

これで、メソッドはを使用selfしており、警告は消えます!


0

Pythonが非静的メソッド(@staticmethodを追加しない)を呼び出すときに最初の引数としてselfを渡すため、Pycharmが警告としてそれを行う理由。Pycharmはそれを知っています。

例:

class T:
    def test():
        print "i am a normal method!"

t = T()
t.test()
output:
Traceback (most recent call last):
  File "F:/Workspace/test_script/test.py", line 28, in <module>
    T().test()
TypeError: test() takes no arguments (1 given)

私はJavaの出身です。Javaでは「self」は「this」と呼ばれ、クラスメソッドの引数としてself(またはthis)を記述する必要はありません。メソッド内で必要に応じて、自分自身を呼び出すことができます。しかし、Pythonはメソッド引数として自分自身を「渡さなければなりません」。

これを理解することで、@ BobSteinの回答のような回避策は必要ありません。


self何で合格?
zerkms

@zerkms '@staticmethod'は 'self'を通過しません
Wu

「Pythonは最初の引数としてselfを渡します... Pycharmはそれを知っています。」だから何?Pycharmはそれを知っています、私はそれを知っています。メソッドをマークする理由は何ですか?
zerkms

@zerkmsは、Pycharmが最初のメソッドparamが「自己」ではないと考えているためです。通常、pplはメソッドparamを設計せず、決して使用しません。Pycharmはあなたが静的メソッドを作成していると考えており、最初のパラメーターが「自分」ではないことを認識していなかったため、デフォルトで警告が表示されます。この混乱は、プログラミング言語の設計によって引き起こされました。混乱を避けるために、プログラミングの設計(良いパターンではないように見えます)に従い、「静的メソッド」を追加することをお勧めします。「自己」を追加する場合はまったく問題ありませんが、必要に応じて使用しないでください。私が言うことは、プログラミングのデザインを理解することによる、単なる別の意見です。
Junyu Wu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.