2008-11-13 4 views
6

아파치 access.log 파일을 특정 방식으로 파이썬 프로그램으로 파싱하고 싶습니다. 객체 지향 프로그래밍에 완전히 익숙하지 않더라도 지금부터하고 싶습니다. 내장 클래스에서 상속하는 것이 맞습니까?

내가 ApacheAccessLog 클래스 을 만들려고하고있다, 나는 지금 상상할 수있는 유일한 것은,이 일을 할 것입니다 것은 '의 readline'방법이다. 이 경우에는 파일 클래스를 상속하는 것이 일반적이므로 올바르게 클래스가 파일 클래스의 인스턴스처럼 작동 할 것인가, 그렇지 않은 것입니까? 그 일을하는 가장 좋은 방법은 무엇입니까?

답변

15

나는 대표보다는 상속을 사용합니다. 이것은 클래스가 파일 객체를 속성으로 포함하고 그것에 readline 메소드를 호출해야 함을 의미합니다. 로거 클래스의 생성자에서 파일 객체를 전달할 수 있습니다.

이 적어도 두 가지 이유가 있습니다

  1. 위임 당신이 readline 방법 (를 입력 오리가 여기에 편리 제공) 구현하는 다른 객체를 사용할 수있는 오브젝트 파일 대신에, 예를 들어, 커플 링을 감소는 .
  2. 파일에서 상속하면 클래스의 공용 인터페이스가 불필요하게 넓어집니다. 아파치 로그의 경우이 방법들이 의미가 없더라도 파일에 정의 된 모든 메소드를 포함합니다.
1

내장 클래스에서 상속받을 수 있습니다. 이 경우 당신이 돈에 맞다고 말할 수 있습니다.
로그는 "파일"이므로 상속을 알리는 메시지가 표시됩니다.

일반 규칙.
개는 "동물"이므로 동물을 상속합니다.
소유자는 "n 개의 동물이 있으므로 동물을 상속하지 않습니다.

1

내장 함수를 상속하는 것이 유용한 경우도 있지만 실제 결과물은 출력물로 무엇을하고 싶은지, 큰 그림 디자인이 무엇인지 등입니다. 필자는 보통 파일 객체를 사용하는 독자를 작성하고 방금 읽은 정보를 유지하는 데 필요한 데이터 클래스를 뱉어냅니다. 그런 다음 나머지 디자인과도 잘 어울리는 데이터 클래스를 쉽게 디자인 할 수 있습니다. 이 경우

1

"내장"클래스를 상속하는 것이 안전해야합니다. 나중에 이러한 클래스를 수정하면 현재 버전과 호환 될 수 있습니다.

그러나 클래스를 내장 클래스에서 제공하는 추가 기능에 실제로 묶고 싶다고 생각해야합니다. 다른 대답에서 언급했듯이 대표단을 대신 사용하는 것이 좋습니다.

상속을 필요로하지 않는 이유의 예로는 java.util.Stack 클래스를 볼 수 있습니다. 벡터를 확장하면 모두의 Vector에 상속됩니다. 이러한 메소드의 대부분은 Stack에 의해 암시 된 계약을 파기합니다. LIFO. Stack 메서드를 API로만 노출하면 내부적으로 Vector를 사용하여 Stack을 구현하는 것이 훨씬 더 낫습니다.구현을 ArrayList 또는 나중에 다른 것으로 변경하는 것은 쉬웠을 것입니다. 상속으로 인해 어느 것도 가능하지 않습니다.

6

저는 자바 배경에서 왔지만 동일한 원칙이 파이썬에 적용될 것이라는 확신이 있습니다. 엄지 손가락의 기준으로 절대 클래스는 상속을 위해 특별히 설계된 클래스가 아니면 구현을 이해하고 제어 할 수없는 클래스에서 상속해야합니다. 이 방법으로 설계된 경우 설명서에이 내용을 명확하게 설명해야합니다.

이유는 상속이 잠재적으로 상속하는 클래스의 구현 세부 정보를 바인딩 할 수 있기 때문입니다.

조쉬 블로흐의 책에서 예제를 사용하려면 '효과적인 자바'

우리는 평생 동안 여기에 추가 된 항목의 수를 계산 할 수 있도록 클래스 ArrayList 클래스를 확장한다면 (반드시 현재 들어있는 숫자는 아님) 우리는 이와 같은 것을 쓰고 싶을지도 모릅니다.

public class CountingList extends ArrayList { 
    int counter = 0; 

    public void add(Object o) { 
     counter++; 
     super.add(0); 
    } 

    public void addAll(Collection c) { 
     count += c.size(); 
     super.addAll(c); 
    } 

    // Etc. 
} 

이제이 확장은 실제로 목록에 추가 된 요소의 수를 정확하게 계산하는 것처럼 보이지만 실제로는 그렇지 않을 수 있습니다. ArrayListaddAll을 구현 한 경우 Collection을 반복하여 각 요소에 대해 addAll 인터페이스 메서드를 호출하면 addAll 메서드를 통해 추가 된 각 요소를 두 번 계산합니다. 이제 우리 클래스의 동작은 구현 세부 사항 ArrayList에 달려 있습니다.

물론 List의 다른 구현을 CountingList 클래스와 함께 사용할 수 없다는 단점이 있습니다. 위에 설명 된 구체적인 클래스를 상속하는 단점도 플러스입니다.

파이썬이 Java와 비슷한 (동일하지 않은 경우) 메소드 디스패치 메커니즘을 사용하므로 동일한 제한 사항이 적용된다는 것을 이해합니다. 파이썬에서 예제를 제공 할 수 있다면 더 유용 할 것입니다.

0

이 경우 위임이 더 나은 전략이라고 답을 찾은 것 같습니다. 그럼에도 불구하고 위임자를 제외하고 내장 클래스를 확장하는 데는 아무런 문제가 없습니다. 특히 언어에 따라 대안이 "원숭이 패치"(http://en.wikipedia.org/wiki/Monkey_patch 참조) 인 경우

관련 문제