web-dev-qa-db-ja.com

pylintの「パブリックメソッドが少なすぎる」というメッセージの意味

いくつかのコードでpylintを実行していますが、「パブリックメソッドが少なすぎます(0/2)」というエラーが表示されます。このメッセージはどういう意味ですか? pylint docs は役に立ちません:

クラスのパブリックメソッドが少なすぎる場合に使用されるため、本当に価値があることを確認してください。

87
monsur

エラーは基本的に、クラスを辞書として扱うので、クラスはjustデータを保存することを意図したものではないと言っています。クラスには、保持するデータを操作するためのメソッドが少なくともいくつか必要です。

クラスが次のように見える場合:

class MyClass(object):
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

代わりに辞書またはnamedtupleの使用を検討してください。クラスが最良の選択と思われる場合は、それを使用します。パイリントは常に何が最善かを知っているわけではありません。

namedtupleは不変であり、インスタンス化時に割り当てられた値は後で変更できないことに注意してください。

101
Blender

あなたがクラスを拡張している場合、私の提案はこの警告を体系的に無効にして、たとえばCeleryタスクの場合に進むことです:

class MyTask(celery.Task):  # pylint: disable=too-few-public-methods                                                                                   
    """base for My Celery tasks with common behaviors; extends celery.Task

    ...             

単一の関数のみを拡張する場合でも、この手法を機能させるにはクラスが必要です。サードパーティのクラスをハッキングするよりも拡張する方が間違いなく優れています。

37
sage

これは、pylintのブラインドルールの別のケースです。

「クラスはデータを保存することを意図したものではありません」-これは誤った記述です。辞書はすべてに適しているわけではありません。クラスのデータメンバーは意味のあるものであり、辞書項目はオプションのものです。証明:dictionary.get('key', DEFAULT_VALUE)を実行してKeyErrorを防ぐことができますが、単純な__getattr__デフォルト。

編集-構造体の推奨される使用方法

回答を更新する必要があります。今-structが必要な場合、2つの素晴らしいオプションがあります:

a)attrsを使用します

これらはそのためのライブラリです:

https://www.attrs.org/en/stable/

import attr

@attr.s
class MyClass(object):  # or just MyClass: for Python 3
    foo = attr.ib()
    bar = attr.ib()

余分なもの:コンストラクター、デフォルト値、検証、__repr__、読み取り専用オブジェクト(namedtuplesを置き換えるため、Python 2)などでも)。

b)dataclasses(Py 3.7+)を使用します

Hwjpのコメントに続いて、dataclassesもお勧めします。

https://docs.python.org/3/library/dataclasses.html

これはattrsとほぼ同じであり、Python 3.7+。

前の回答の残り

NamedTupleは大きくありません-特にpython 3's typing.NamedTuplehttps://docs.python.org/3/library/typing.html#typing.NamedTuple -「NamedTupleから派生したクラス」パターンを必ずチェックしてください。 Python 2-namedtuplesは文字列の説明から作成されます-くて悪いです。 "文字列リテラル内のプログラミング"は愚かです。

現在の2つの答え(「他の何かを使用することを検討しますが、pylintは常に正しいとは限りません」-受け入れられた答えと「pylint抑制コメントを使用」)に同意しますが、私は自分の提案を持っています。

これをもう一度指摘しましょう。一部のクラスは、データを保存することを意味していますjust

オプションもconsider-property- iesを使用します。

class MyClass(object):
    def __init__(self, foo, bar):
        self._foo = foo
        self._bar = bar

    @property
    def foo(self):
        return self._foo

    @property
    def bar(self):
        return self._bar

上記には読み取り専用のプロパティがあり、これは値オブジェクト(ドメイン駆動設計のプロパティなど)には問題ありませんが、セッターを提供することもできます-このようにして、クラスはあなたが持っているフィールドの責任を取ることができます-たとえば検証などを行います(セッターがある場合は、コンストラクターでそれらを使用して割り当てることができます。つまり、self.foo = foo直接ではなくself._foo = foo、ただし注意が必要ですが、セッターは他のフィールドがすでに初期化されていると想定している場合があり、コンストラクターでカスタム検証が必要です。

7
Tomasz Gandor

クラスに追加のメソッドを追加しました

def __str__(self):
    return self.__class__.__name__

問題が解決しました

1
Sean Bradley