파일 린트의“너무 적은 공개 방법”메시지는 무엇을 의미합니까?


110

일부 코드에서 pylint를 실행 중이며 "Too few public methods (0/2)"오류가 표시됩니다. 이 메시지는 무엇을 의미합니까? pylint의 문서가 도움이되지 않습니다 :

클래스에 공개 메서드가 너무 적을 때 사용되므로 그만한 가치가 있는지 확인하십시오.


1
수업은 어떻게 생겼습니까? 클래스는 데이터 저장 이외의 작업을 수행합니까?
Blender

1
수업이하는 일은 데이터를 저장하는 것입니다.
monsur

2
음, 문제가 있습니다. 클래스는 데이터를 저장하기위한 것이 아닙니다. 이것이 사전 및 목록과 같은 데이터 구조의 목적입니다.
Blender

흥미 롭군요, 감사합니다! 파일 린트 오류 메시지가 더 유용 할 수 있습니다. 어쨌든 귀하의 의견을 답변으로 바꾸면 승인하겠습니다.
monsur

6
그러나 "적다"의 정의는 어디에 있습니까? 정확히 한 가지 방법이 있습니다. 그것이 클래스가 존재하는 이유입니다. pylint는 "몇"을 어떻게 정의합니까? 2 개 이상? 왜?
Zordid

답변:


124

이 오류는 기본적으로 클래스를 의미하지 않는 것을 말한다 단지 당신이 기본적으로 사전으로 클래스를 치료하고 같은 데이터를 저장. 클래스에는 보유한 데이터에 대해 작동 할 수있는 최소한 몇 가지 메서드가 있어야합니다.

수업이 다음과 같은 경우 :

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

사전 또는 namedtuple대신 사용을 고려하십시오 . 수업이 최선의 선택처럼 보이더라도 사용하십시오. 파일 린트는 항상 최선이 무엇인지 알지 못합니다.

그 노트를 수행 namedtuple불변이며, 인스턴스에 할당 된 값은 나중에 수정할 수 없습니다.


72
"pylint 가장 무엇을 알고하지 않습니다"에 대한 한 - 당신이 필요로하는 것은 "구조체"인 경우 자신의 판단을 사용하지만 원칙적으로하는을 사용 dict하거나 namedtuple. 객체에 로직을 추가하고 싶을 때 클래스를 사용합니다 (예를 들어, 객체가 생성 될 때 발생하기를 원하고, 추가 될 때 발생하는 특별한 일이 필요하고, 이에 대해 몇 가지 작업을 수행하고, 방법을 제어하고 싶을 때) 표시 등)
Burhan입니다 칼리드

자세한 답변에 감사드립니다! 내 사용 사례는 Burhan이 언급 한 것과 비슷합니다. 데이터가 생성 될 때 데이터를 처리하고 있습니다.
monsur

6
이 오류는 클래스 정의 내부에 Meta (메타 클래스)가있는 경우 의미가 없습니다.
alexander_ch

11
namedtuple짜증나게-추악한 구문을 갖는 것 외에도 문서화하거나 기본값을 쉽게 제공 할 수 없습니다.
rr-

6
사용할 때마다 namedtuple결정을 후회했습니다. 명명 된 액세스와 인덱싱 된 액세스 속성을 모두 허용하는 것은 일관성이 없습니다.
theorifice dec

39

수업을 확장하는 경우에는이 경고를 체계적으로 비활성화하고 예를 들어 Celery 작업의 경우 계속 진행하는 것이 좋습니다.

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

    ...             

단일 함수 만 확장하더라도이 기술이 작동하도록하려면 클래스가 반드시 필요하며 확장은 타사 클래스를 해킹하는 것보다 확실히 낫습니다!


이 실패, pre-commit은 이제 나에게 제공됩니다 : 잘못된 옵션 값 'too-few-public-method'(bad-option-value)
Mercury

메소드에 's'를 포함 했습니까? 잘못된 옵션 값 메시지에 없습니다.
sage

4
아마도 이것을 비활성화하는 더 좋은 방법 은 구성 파일 min-public-methods=0[BASIC]섹션에서 설정하는 것입니다. 이렇게하면 구성 변경과 함께 항목을 활성화 및 비활성화 한 이유에 대한 자세한 설명을 쉽게 추가 할 수있는 모든 항목 disable=( [MESSAGE CONTROL]) 과는 별도의 줄에 배치 할 수 있습니다.
CJS

15

이것은 pylint블라인드 규칙의 또 다른 경우입니다 .

"클래스는 데이터를 저장하기위한 것이 아닙니다"-이것은 잘못된 진술입니다. 사전이 모든 것에 좋지는 않습니다. 클래스의 데이터 멤버는 의미 있고 사전 항목은 선택 사항입니다. 증거 : dictionary.get('key', DEFAULT_VALUE)를 방지하기 위해 할 수 KeyError있지만 __getattr__기본값으로 는 간단하지 않습니다 .

편집-구조체 사용에 권장되는 방법

내 답변을 업데이트해야합니다. 지금-필요한 경우struct 두 가지 훌륭한 옵션이 있습니다.

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__, 읽기 전용 객체 ( namedtuplesPython 2에서도 를 대체하기 위해) 등을 작성하지 않습니다 .

b) 사용 dataclasses(Py 3.7+)

hwjp의 의견에 따라 다음을 권장합니다 dataclasses.

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

이 기능은 거의 비슷하며 attrsPython 3.7 이상을 제외하고 추가 종속성이없는 표준 라이브러리 메커니즘 ( "배터리 포함")입니다.

이전 답변의 나머지

NamedTuple크지 않다 - 특히 파이썬 3 개의 전에 typing.NamedTuple: https://docs.python.org/3/library/typing.html#typing.NamedTuple - 당신은 확실히 '에서 파생 된 클래스 체크 아웃해야 NamedTuple패턴을 ". 파이썬 2-namedtuples 문자열 설명에서 생성 된-추악하고 나쁘고 "문자열 리터럴 내부 프로그래밍"바보입니다.

나는 현재의 두 가지 답변 ( "다른 것을 사용하는 것을 고려하지만 파일 린트가 항상 옳은 것은 아닙니다"-수락 된 답변과 "주석 억제 주석 사용")에 동의하지만, 나만의 제안이 있습니다.

나 하나에서 더 많은 시간을이 문제를 지적하자 일부 클래스는 의미 단지 데이터를 저장하는 데.

이제 고려할 옵션 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

위에는 읽기 전용 속성이 있습니다. 이는 Value Object (예 : Domain Driven Design의 속성과 같은)에 적합하지만 setter를 제공 할 수도 있습니다. 이렇게하면 클래스가 보유한 필드에 대해 책임을 질 수 있습니다. 몇 가지 유효성 검사 등을 수행합니다. (setter가있는 경우 self.foo = foo직접 대신 생성자에서이를 사용하여 할당 할 수 self._foo = foo있지만 신중하게 설정자는 다른 필드가 이미 초기화되었다고 가정 할 수 있으며 생성자에서 사용자 지정 유효성 검사가 필요합니다) .


2
Python 3.7 이상에서 데이터 클래스는 명명 된 튜플의 추악함을 해결하는 좋은 솔루션을 제공하며 DDD 값 개체에 완벽 합니다.
hwjp 2019

동의합니다. 2020 년부터는 표준 방식입니다. 광범위한 버전 범위의 메커니즘 (내가 기억한다면 2.7, 3.3+)을 가지려면 attrs라이브러리를 사용할 수 있습니다. 실제로 dataclasses모듈 을 생성하는 청사진이었습니다 .
Tomasz Gandor

namedtuples상속에 대한 이상한 구문이 있습니다 ... 모든 클래스가 하나를 사용하여 이름이 지정된 튜플임을 알고 __new__대신 __init__. dataclasses이러한 제한이 없습니다
에릭 Aronesty

4

상사가 단일 책임 원칙을 기대하는 것은 어렵지만 Pylint는 아니오라고 말합니다. 따라서 클래스가 단일 책임 원칙을 위반하도록 두 번째 방법을 클래스에 추가하십시오. 단일 책임 원칙을 얼마나 멀리 가져야하는지는 보는 사람의 눈에 달려 있습니다.

내 수정,

클래스에 메서드를 추가 했으므로 이제 두 가지 작업을 수행합니다.

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

지금 내 클래스를 2 개의 개별 파일로 분할해야하는지, 모듈도 마찬가지인지 궁금합니다.

문제는 해결되었지만 하루 종일 사양에 대해 논쟁하는 동료 들과는 어울리지 않았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.