2013-10-03 3 views
3

클래스를 특별한 값으로 사용하는 것은 파이썬에서 추한가? 내가 어떤 "정상"유형의 결과는 숫자 것으로 예상 경우, 또는클래스를 특별한 값으로 사용 하시겠습니까?

def find_result(): 
    result = None 
    # do something to find the result, even recursing 
    return result 

r = find_result() 
if r is None: 
    raise Exception("we have no result") 

이 완벽하게 작동합니다 :

이를 생각해 보자.

하지만 임의의 데이터 구조가 있고 그 결과가 None에서 다른 구조로 바뀔 수 있다면 어떻게 될까요? 내가 내 경우에 한 일은이었다 같은 :

class NoResult: 
    """i'm even less than `None`.""" 
    pass 

def query(data, path): 
    result = NoResult 
    # traverse and recurse into the data structure 
    return result 

r = query() 
if r is NoResult: 
    raise Exception("our hands are empty") 

그것은 작동하지만 내가 조금, 여기 가난한 클래스를 학대 해요 느낌을 떨쳐 버릴 수도 숨어 진짜 위험이있을 수 있습니다 내부.

사실입니까? 내가 수업을 학대하는거야? 아니면 그것은 내 알고리즘이 "special None"에 의존 할 필요가 있다면 그냥 쓰다니까?

+2

아무 것도 반환하지 않고 'find_result'에서 예외를 발생시키지 않는 이유는 무엇입니까? 예외를 발생시키는 전체 아이디어는 특별한 반환 값을 인식하는 것과는 독립적 인 대체 오류 검색 메커니즘을 제공하는 것입니다. – chepner

+0

@chepner 내가 더 재귀 할 필요가 있었기 때문에 나는 그것을 좋아했다. 그리고 내가 최고 전화로 돌아갈 때까지 검색을 멈추고 싶다는 것을 결코 알지 못했다. 이제는 적절한 예외 처리를 생각해 보면 더 좋을 수도 있습니다 ... –

답변

5

그것은 센티넬라고, 당신이 그것을 위해 고유 한 개체를 사용할 수는 :

sentinel = object() 

if r is sentinel: 
    raise Exception(..) 

는 여기에 간단한 object() 예를 대신 사용자 정의 클래스를 사용했다.

커스텀 클래스는 아마도 더 많은 자체 문서화가 가능하다는 장점이 있습니다. API 이 있으면 API 사용자 (코드 일 수 있음)에게 객체를 전달할 수 있으며 명시 적 클래스가 더 좋습니다. API의 블랙 박스에서 사용하기 위해서는 object()이 좋습니다.

이제 경계를 반환하는 시점에서 예외를 발생시키는 것을 고려할 수 있습니다. 언제든지을 다시 catch 할 수 있습니다.

+0

@AloisMahdal : 예; 그게 혼란 스러웠다. 문장을 약간 변경했습니다. –

+0

방금 ​​전에 사용한 코드를 사용하여 클래스를 직접 사용하는 또 다른 이점을 발견했습니다 (즉, 인스턴스 나 일반 객체가 아닌). 인쇄 할 때'가 아닌'mymodule.NoResult'가됩니다 at 0x12345>'(Python 2.7)을 참조하십시오. 그것은 완전히 자유 롭습니다 ('__str__'는 필요 없습니다, 단지'클래스 X : 패스') 그리고 훨씬 더 읽기 쉽습니다. 특히 다중 센티널을 사용하고 싶다면 더욱 그렇습니다. 따라서 인쇄를 계획하지 않더라도 여전히 디버깅에 더 좋으며 몰래 들어갈 경우 적어도 사용자/사용자를 적절한 위치로 보낼 수 있습니다. –

+0

내가 언급 한 '자체 문서화'부분입니다. :-) –

2

Martijn이 제안한 또 다른 접근 방식을 추가하기 위해 예외 메커니즘을 사용하여 find_result이 처음에는 "결과 없음"예외를 발생시킨 다음 호출자가 처리 방법을 결정하게합니다.

def find_result(): 
    result = None 
    if (...): 
     raise NoResultException("details") 
    return result 

try: 
    r = find_result() 
except NoResultException: 
    raise Exception("we have no result") 
관련 문제