파이썬 믹스 인은 안티 패턴입니까?


34

나는 pylint다른 정적 분석 도구가 모든 것을 알지 못한다는 것을 알고 있으며 때로는 그들의 조언에 불복종해야합니다. (이것은 conventions 뿐만 아니라 다양한 메시지 클래스에 적용됩니다 .)


내가 같은 수업이 있다면

class related_methods():

    def a_method(self):
        self.stack.function(self.my_var)

class more_methods():

    def b_method(self):
        self.otherfunc()

class implement_methods(related_methods, more_methods):

    def __init__(self):
        self.stack  = some()
        self.my_var = other()

    def otherfunc(self):
        self.a_method()

분명히, 그것은 고안되었습니다. 원하는 경우 더 좋은 예가 있습니다 .

이 스타일은 "mixins"를 사용한다고합니다.

다른 도구와 마찬가지로, pylint요금이 코드는 -21.67 / 10주로는 생각 때문에 more_methods그리고 related_methods이없는 self나 속성 otherfunc, stack,하는 Nd my_var코드를 실행하지 않고, 그것은 분명히 볼 수 없기 때문에 related_methodsmore_methods혼합에에 있습니다 implement_methods.

컴파일러와 정적 분석 도구가 항상 Halting Problem을 해결할 수 는 없지만 상속 된 implement_methods것을 보면 이것이 완전히 유효하다는 것을 알 수 있습니다. 매우 쉬운 일이라고 생각합니다.

정적 분석 도구가이 유효한 OOP 패턴을 거부하는 이유는 무엇입니까?

어느 한 쪽:

  1. 그들은 심지어 상속을 확인 하려고 시도 하지 않거나

  2. 믹스 인은 관용적이고 읽기 쉬운 파이썬에서는 사용하지 않는 것이 좋습니다


# 1 (에만 정의 된 것을 사용 pylint하는)을 상속받는 내 클래스에 대해 말하면 불평 하지 않기 때문에 분명히 잘못되었습니다 .unittest.TestCaseself.assertEqualunittest.TestCase

믹스 인은 비 피톤 적이거나 낙담합니까?


1
이것은 나쁜 질문입니까? 주제가 맞지 않습니까? 대답 할 수 없습니까? 내가 바보 야? 사람들은 DV를 할 수 있지만 개선을 원치 않습니다.
고양이

1
사람들에게 "이것은 (안티) 패턴"또는 "이것은 (비) 파이 토닉"이라고 묻는 데 지칠 수있는 사람들이 있습니다.

9
@MichaelT 괜찮습니다. 그러면 질문 검토를 중단 할 수 있습니다.
Katana314

2
@tac 사람들은 여러 가지 이유로 다운 투표를 할 것입니다. 그러나 그 이유를 말할 필요는 없습니다. 다운 투표 버튼에는 "이 질문은 어떤 연구 노력도 보여주지 않습니다; 불분명하거나 유용하지 않습니다"라고 말하는 툴팁이 있습니다. 허용되는 답변. 8 up 및 1 down은 실제로 downvotes가 무료 인 질문에서 특히 좋습니다. 당신을 실망시키지 마십시오. 건배.
Aaron Hall

@AaronHall 나는 사람들이 자신의 투표로 자신이 좋아하는 것을 할 수 있다는 것을 알고 있습니다.
고양이

답변:


16

믹스 인은 도구에서 고려한 사용 사례가 아닙니다. 그것은 반드시 나쁜 유스 케이스라는 것을 의미하지는 않지만 파이썬에서는 드문 경우입니다.

믹스 인이 특정 상황에서 적절하게 사용되는지 여부는 또 다른 문제입니다. 내가 가장 자주 본 믹스 인 안티 패턴은 오직 하나의 조합 만 혼합하려는 경우 믹스 인을 사용합니다. 그것은 신 클래스를 숨기는 원형 길입니다. 믹스 인 중 하나를 교체하거나 제거 해야하는 이유를 지금 생각할 수 없다면 믹스 인이되어서는 안됩니다.


그래, 그것은 신의 대상이다. 이 경우 CPU가 신 (God) 객체 인 것이 좋다고 주장합니다.
고양이

15

나는 Mixins가 절대적으로 Pythonic 일 수 있다고 생각합니다. 그러나, 린터를 침묵시키고 믹스 인의 가독성을 향상시키는 관용적 방법은 (1) 믹스 인의 자녀가 구현해야하는 방법 을 명시 적으로 정의하는 추상적 인 방법 을 정의하고 (2) 사전 정의하는 것입니다. None하위를 초기화해야하는 Mixin 데이터 멤버에 대한 값 필드

이 패턴을 예제에 적용 :

from abc import ABC, abstractmethod


class related_methods():
    my_var = None
    stack = None

    def a_method(self):
        self.stack.function(self.my_var)


class more_methods(ABC):
    @abstractmethod
    def otherfunc(self):
        pass

    def b_method(self):
        self.otherfunc()


class implement_methods(related_methods, more_methods):
    def __init__(self):
        self.stack  = some()
        self.my_var = other()

    def otherfunc(self):
        self.a_method()

2
당신의 답변에 +1, abstract other(self): pass일이 내 것에 대한 린터의 혼란을 거래 하지만
cat

@abstractmethod없이 더 혼란 스럽습니다. ;-) Java를 먼저 시작했기 때문에 이것은 나에게 좋습니다.
Chris Huang-Leaver

9

나는 믹스 인이 좋을 것이라고 생각하지만,이 경우에는 pylint가 옳다고 생각합니다. 면책 조항 : 의견 기반의 내용은 다음과 같습니다.

믹스 인을 포함한 좋은 수업은 분명한 책임이 있습니다. 이상적으로, 믹스 인은 액세스하려는 모든 상태와이를 처리 할 논리를 전달해야합니다. 예를 들어 좋은 믹스 인은 last_updatedORM 모델 클래스에 필드를 추가하고 ,이를 설정하기위한 논리를 제공하며, 가장 오래된 / 최신 레코드를 검색하는 방법을 제공 할 수 있습니다 .

선언되지 않은 인스턴스 멤버 (변수 및 메소드)를 참조하면 약간 이상하게 보입니다.

올바른 접근 방식은 현재 진행중인 작업에 따라 다릅니다.

관련 상태 비트와 혼합되어있을 수 있습니다.

현재 믹스 인을 통해 배포하는 메서드가 기본 클래스에있는 반면 다른 수준의 구현 차이는 하위 클래스에 속하는 다른 클래스 계층 구조 일 수 있습니다. 이것은 스택 작업과 함께 귀하의 경우에 가장 적합합니다.

메소드를 추가하는 클래스 데코레이터 일 수 있습니다. 메소드 생성에 영향을 미치기 위해 데코레이터에 인수를 전달해야 할 때 일반적으로 의미가 있습니다.

문제를 설명하고 더 큰 디자인 문제를 설명하면 어떤 경우에 반 패턴이 있는지 논쟁 할 수 있습니다.


6

린 터는 클래스를 믹스 인으로 사용한다는 것을 인식하지 못합니다. Pylint는 클래스 이름 끝에 접미사 'mixin'또는 'Mixin'을 추가하면 믹스 인이 사용된다는 것을 알고 있습니다.

linter_without_mixins linter2_with_mixin

믹스 인 자체는 나쁘지 않거나 좋지 않으며 단지 도구 일뿐입니다. 당신은 그들을 잘 사용하거나 나쁜 사용으로 만듭니다.


2
이것은 댓글처럼 더 읽습니다. 답변하는 방법
gnat

2
나는 내가 그렇지 않으면 그 힌트에 대해 알고 거라고 생각하지 않기 때문에이 가치있는 대답이다
고양이

1

믹스 인은 괜찮습니까?

파이썬 믹스 인은 안티 패턴입니까?

믹스 인은 사용하지 않는 것이 좋습니다. 다중 상속의 좋은 유스 케이스입니다.

당신의 린터가 왜 불평합니까?

Pylint은 어디를 모르기 때문에 분명히 불평 otherfunc, stack그리고 my_var 에서오고있다.

하찮은?

이 두 가지 방법을 문제의 예 또는 여기에 표시된 더 간단한 링크 된 예에서 별도의 부모 클래스로 분리해야 할 정당한 이유는 없습니다.

201
202 class OpCore():
203     # nothing runs without these
204
205 class OpLogik(): 
206     # logic methods... 
207 
208 class OpString(): 
209     # string things
210 
211 
212 class Stack(OpCore, OpLogik, OpString): 
213 
214     "the mixin mixer of the above mixins" 

믹스 인 및 소음 비용

당신이하는 일의 비용은 린터 보고서 노이즈를 만드는 것입니다. 이 노이즈는 코드에서 더 중요한 문제를 모호하게 할 수 있습니다. 이것은 무게를 측정하는 중요한 비용입니다. 또 다른 비용은 상호 관련 코드를 다른 네임 스페이스로 분리하여 프로그래머가 의미를 찾기 어렵게 만들 수 있다는 것입니다.

결론

상속은 코드 재사용을 허용합니다. 믹스 인으로 코드를 재사용하면 다른 비용보다 큰 가치를 창출 할 수 있습니다. 코드 라인의 코드 재사용 / 중복 제거를 얻지 못하면 믹스 인에 대해 많은 가치를 얻지 못할 수 있으며 그 시점에서 노이즈 비용이 이점보다 더 크다고 생각합니다.


연결되지 않은 간단한 예제에서 그것들을 분리해야 할 좋은 이유가 있습니다. 수학을 구현하는 전체 클래스의 일부, 문자열을 구현하는 클래스 등을 가지고있을 때 코드를 구성하는 것이 더 쉽습니다. Forth Soup을 얻으려면
고양이

"또 다른 비용은 코드를 다른 네임 스페이스로 분리하여 프로그래머가 의미를 발견하기 어렵게 만들 수 있다는 것입니다."-아니요, 전혀 그렇지 않습니다. 클래스 네임 스페이스는보다 쉽게 방법의 그룹이 무엇을 말할 수 있도록, 그리고 누군가가 스택을 사용하고자 할 때, 그들은 넷째 수프가 아닌 개별 성분 구현 / 호출해야합니다
고양이

@cat은 아마도 큰 프로젝트에서 사용되지 않았기 때문에 아마도 믹스 인 사용의 요점을 실제로 지원하지는 않습니다. 둘 다 믹스 인이 사용 된 시간을 한 번만 표시합니다.이 경우 구현을 한 곳에 두는 것이 더 나은 스타일과 구성입니다. 클래스 간 공통 기능을 원하지만 공통 기본 클래스를 원하지 않는 경우를 보여줄 수 있다면 믹스 인을 사용하는 것입니다. 린트 질문 옆에있는 것이 있습니다 (UltraBird가 잘 대답했습니다). 그러나 이것은 일반적으로 mixin 적용 가능성에 관한 귀하의 질문에 대답합니다.
dlamblin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.