いくつかのコードでpylintを実行していますが、「パブリックメソッドが少なすぎます(0/2)」というエラーが表示されます。このメッセージはどういう意味ですか? pylint docs は役に立ちません:
クラスのパブリックメソッドが少なすぎる場合に使用されるため、本当に価値があることを確認してください。
エラーは基本的に、クラスを辞書として扱うので、クラスはjustデータを保存することを意図したものではないと言っています。クラスには、保持するデータを操作するためのメソッドが少なくともいくつか必要です。
クラスが次のように見える場合:
class MyClass(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
代わりに辞書またはnamedtuple
の使用を検討してください。クラスが最良の選択と思われる場合は、それを使用します。パイリントは常に何が最善かを知っているわけではありません。
namedtuple
は不変であり、インスタンス化時に割り当てられた値は後で変更できないことに注意してください。
あなたがクラスを拡張している場合、私の提案はこの警告を体系的に無効にして、たとえばCeleryタスクの場合に進むことです:
class MyTask(celery.Task): # pylint: disable=too-few-public-methods
"""base for My Celery tasks with common behaviors; extends celery.Task
...
単一の関数のみを拡張する場合でも、この手法を機能させるにはクラスが必要です。サードパーティのクラスをハッキングするよりも拡張する方が間違いなく優れています。
これは、pylint
のブラインドルールの別のケースです。
「クラスはデータを保存することを意図したものではありません」-これは誤った記述です。辞書はすべてに適しているわけではありません。クラスのデータメンバーは意味のあるものであり、辞書項目はオプションのものです。証明:dictionary.get('key', DEFAULT_VALUE)
を実行してKeyError
を防ぐことができますが、単純な__getattr__
デフォルト。
回答を更新する必要があります。今-struct
が必要な場合、2つの素晴らしいオプションがあります:
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)などでも)。
dataclasses
(Py 3.7+)を使用しますHwjpのコメントに続いて、dataclasses
もお勧めします。
https://docs.python.org/3/library/dataclasses.html
これはattrs
とほぼ同じであり、Python 3.7+。
NamedTuple
は大きくありません-特にpython 3's typing.NamedTuple
: https://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
、ただし注意が必要ですが、セッターは他のフィールドがすでに初期化されていると想定している場合があり、コンストラクターでカスタム検証が必要です。
クラスに追加のメソッドを追加しました
def __str__(self):
return self.__class__.__name__
問題が解決しました