2014-11-12 2 views
0

이것은 아마도 너무 일반적인 질문 일 뿐이지 만 여전히 귀찮습니다. 일반적으로, 더 나은 방법은 무엇입니까? (그리고 왜) : 기본 클래스를 프록시 처리하거나 서브 클래 싱하는 것입니까? base 보통 표준 클래스 중 하나를 의미합니다. 표준 클래스는 대개 Python으로 구현되지 않습니다.기본 클래스를 프록 싱하거나 하위 클래스 화 하시겠습니까?

더 구체적인 질문은 다음과 같습니다. 그래프 가장자리에 대한 개체를 만들고 싶습니다. 그래프 엣지는 본질적으로 두 개의 정점 쌍입니다. 버텍스는 임의의 해시 가능 객체 일 수있다. 나는 가장자리가 frozenset 노출보다 더 많은 방법을 폭로하기를 바랍니다. 그래서 내가

class Edge(object): 
    def __init__(self, *args): 
     self._frozenset = frozenset(*args) 

    def __len__(self): 
     return len(self._frozenset) 

    def ... 

첫 번째 방법의 장점

class Edge(frozenset): 
    def my_method(self, *args): 
     return 3 

또는

내가 덜 쓸 필요가 있다는 것입니다 여부를 궁금해 (나는 모든 원래의 방법을 복제 할 필요가 없기 때문에). 그러나 두 번째 방법은 어떤면에서는 더 안전 해 보입니다. 그것은 또한 더 융통성이 있기 때문에, 내가 원한다면 과 같은 frozenset이 노출하는 몇 가지 방법을 피할 수 있기 때문에 더 유연합니다.

첫 번째 방법은 전달 된 인수의 개수와 관련된 문제도 발생시킵니다. 그걸 제어하고 싶다면 아마 frozenset.__new__을 덮어 써야합니다. 다른 한편, 첫 번째 방법은 아마도 프록시가 약간의 오버 헤드를 발생시키기 때문에 일반적으로 더 빠를 것입니다.

중요한지는 잘 모르겠지만 대개 Python 2.7로 작성합니다.

답변

1

질문해야 할 질문은 다음과 같습니다. my class is 또는 my class has? 즉 일반적인 질문과 상속 비교 즉, Edgefrozenset입니까, 아니면 내부 용으로 사용 되나요?

클래스의 제 3 자 사용자라고 생각하십시오. Edge 개체가 생성됩니다. API에 대해 살펴 보겠습니다. 뭘보고 싶니? 아마 당신이 .do_what_edges_do() ... uhmm, 마찬가지로 Edge 논리 도메인과 상호 작용할 수 있도록 방법, 그리고 당신이 조성물에 갈 것을 나에게 분명하다이 경우 .union() 또는 .isdisjoint(),

좋아하지 것. 의심 스러울 때는 작곡을 들어라.

그러나 API에서 frozenset의 일부 메소드를 직접 노출하고자 할 수 있습니다. 파이썬은 그렇게 할 수있는 훌륭한 메커니즘을 가지고 있지만, 일반적인 y와 매직 메소드를 구분해야합니다.

정상적인 방법 :

그냥 당신이 노출하고자하는 방법의 목록을 선언하고 __getattr__를 사용합니다. 예를 들어, (이 학습의 목적을 위해 단지이다 그들이 frozenset에 존재하지 않는)의 당신이 방법을 'ABC'와 'CDE'를 노출하고 싶은 말은하자

class Edge(object): 
    .. 

    _exposed_methods = ['abc', 'cde'] 

    def __getattr__(self, item): 
    if item in self._exposed_methods: 
     return getattr(self, item) 

    raise AttributeError 

매직 방법 :

이전 메카니즘은 매직 메소드에서는 작동하지 않습니다. 파이썬은 성능을 위해 그것을 건너 뜁니다. 이 경우에는 명시 적으로 선언해야합니다.예를 들어, 유용 하나 __len__

class Edge(object): 
    .. 

    def __len__(self): 
    return len(self._my_set) 

편집 코멘트

을 읽고 나면 당신은 의미 결정을해야한다. Edge가 어떤 객체를 포함해야하는지 모릅니다. 그래서 Item objs라고합시다. 이제 문제는 코드의 API에서 어떤 메소드를 제공하겠습니까?

  • get_items? 이것은 Item의 개념을 강조합니다. 이 경우 Item으로 채워지는 컬렉션과 같은 컬렉션을 반환하는 것이 옳습니다. 이 콜렉션에 메소드를 추가하고 싶다고 말했기 때문에, 이것은 아마도 당신이하고 싶은 것이 아닙니다.

  • 또는 get_edge? 이것은 Edge의 개념을 더 중요하게합니다. 이 경우 자신의 Edge 클래스의 인스턴스를 반환해야합니다. 모두frozenset에 의해 노출 된 방법은 Edge 개념에 의미가 있습니다. 상속을 고려하십시오. 그렇지 않으면 작곡을하고 의미있는 것만을 폭로하십시오 (위에서 설명한 메커니즘을 사용하십시오).

+0

감사합니다. 그러나 나에게 이것은 분명하지 않다. 좀 더 추상적 인 생각을 가진 사람들은'if edge1() & edge2()'(예를 들어'edge1'과'edge2'는 집합과 같이 교차)와 같은 것을 검사 할 수 있기를 원합니다. – Bach

+0

어쨌든, 저에게 가장자리 **는 불변의 집합입니다. 아직도'frozenset'을 서브 클래스 화하는 것에는 꽤 많은 소란이 있습니다. 그래서 이것이 올바른 일이라는 것을 확신하지 못합니다. – Bach

+0

그럼 그냥 세트라면, 세트를 사용하십시오. 특별한 의미 나 기능이 필요하지 않은 경우에도 왜 자신 만의 클래스를 만들까요? – bgusach