문제

나는 최근에 자신에게 파이썬을 가르치고 있었고 코드 실행 전에 오류 확인과 관련하여 LBYL/EAFP 관용구를 발견했습니다. 파이썬에서는 인정 된 스타일이 EAFP 인 것 같습니다. 언어와 잘 어울리는 것 같습니다.

lbyl (오크 전, 와이ou EAP):

def safe_divide_1(x, y):
    if y == 0:
        print "Divide-by-0 attempt detected"
        return None
    else:
        return x/y

EAFP (이것의 이자형Asier SK 에프보다 단단함 적기):

def safe_divide_2(x, y):
    try:
        return x/y
    except ZeroDivisionError:  
        print "Divide-by-0 attempt detected"
        return None

내 질문은 이것입니다 : 나는 Java와 C ++ 배경에서 나오는 기본 데이터 검증 구성으로 EAFP를 기본 데이터 검증 구성으로 사용하는 것에 대해 들어 본 적이 없습니다. EAFP는 Java에서 사용하는 것이 현명한 것이 있습니까? 아니면 예외에서 너무 많은 오버 헤드가 있습니까? 예외가 실제로 던져 질 때 오버 헤드 만 있다는 것을 알고 있으므로 EAFP의 간단한 방법이 왜 사용되지 않는지 확실하지 않습니다. 선호도입니까?

도움이 되었습니까?

해결책

개인적으로, 나는 이것이 컨벤션에 의해 백업된다고 생각합니다. EAFP는 결코 좋은 방법이 아닙니다. 다음과 같은 것으로 볼 수 있습니다.

if (o != null)
    o.doSomething();
else
    // handle

반대로 :

try {
    o.doSomething()
}
catch (NullPointerException npe) { 
    // handle
}

또한 다음을 고려하십시오.

if (a != null)
    if (b != null)
        if (c != null)
            a.getB().getC().doSomething();
        else
            // handle c null
    else
        // handle b null
else
    // handle a null

이것은 훨씬 덜 우아하게 보일 수 있습니다 (예, 이것은 조잡한 예입니다 - 나와 함께 곰). NullPointerException, 그리고 어디에서 그리고 왜 그것을 얻었는지 알아 내려고 노력하십시오.

드문 상황을 제외하고는 EAFP를 사용하지 않아야합니다. 또한 문제를 제기 한 이후 : 예, 시도 캐치 블록은 약간의 오버 헤드가 발생합니다 예외가 발생하지 않더라도.

다른 팁

파일에 액세스하는 경우 LBYL과 관련된 작업이 원자가 아니며 파일 시스템이 보는 시간과 도약 시간 사이에 파일 시스템이 변경 될 수 있기 때문에 EAFP는 LBYL보다 신뢰할 수 있습니다. 실제로 표준 이름은 TOCTOU- 점검 시간, 사용 시간입니다. 부정확 한 점검으로 인한 버그는 TOCTOU 버그입니다.

고유 한 이름이 있어야하는 임시 파일을 만드는 것을 고려하십시오. 선택한 파일 이름이 아직 존재하는지 여부를 찾는 가장 좋은 방법은 파일이 이미 존재하는 경우 (POSIX/UNIX 용어로 O_EXCL 플래그로 open()). 파일이 이미 존재하는지 테스트하려고하면 (아마도 access()), "아니오"라고 말하는 시간과 파일을 만들려고 할 때 사이에 누군가 또는 다른 것이 파일을 만들 수 있습니다.

반대로, 기존 파일을 읽으려고한다고 가정하십시오. 파일이 존재한다는 점검 (lbyl)은 "거기에있다"는 말을 할 수 있지만 실제로 열면 "거기에 없다"는 것을 알 수 있습니다.

이 두 경우 모두 최종 작업을 확인해야하며 LBYL은 자동으로 도움이되지 않았습니다.

(SUID 또는 SGID 프로그램을 엉망으로 만드는 경우 access() 다른 질문을합니다. LBYL과 관련이있을 수 있지만 코드는 여전히 실패 가능성을 고려해야합니다.)

Python과 Java의 예외 예외 비용 외에도 철학 / 태도에는 차이가 있음을 명심하십시오. Java는 클래스/메소드 서명의 명시적이고 자세한 선언이 필요한 유형 (및 기타 모든)에 대해 매우 엄격하게 노력합니다. 그것은 당신이 어떤 시점에서든 정확히 어떤 유형의 객체를 사용하고 있는지, 그리고 그것이 할 수있는 일을 정확히 알아야한다고 가정합니다. 대조적으로, Python의 "Duck Typing"은 객체의 명백한 유형이 무엇인지 확실히 알지 못한다는 것을 의미합니다. 이런 종류의 관용 환경에서, 유일한 제정신 태도는 일이 효과가 있다고 가정하지만, 그렇지 않으면 결과를 처리 할 준비가되어 있습니다. Java의 자연스러운 제한성은 그러한 캐주얼 접근 방식에 적합하지 않습니다. (이것은 접근이나 언어를 반박하기위한 것이 아니라, 이러한 태도는 각 언어의 관용구의 일부라고 말하며, 다른 언어 사이의 관용구를 복사하면 종종 어색함과 의사 소통이 좋지 않을 수 있습니다 ...)

예외는 Java보다 Python에서 더 효율적으로 처리됩니다. 부분적으로 왜 당신이 그 구성을 파이썬에서 볼 수 있는지. Java에서는 그러한 방식으로 예외를 사용하는 것이 더 비효율적입니다 (성능 측면에서).

이 코드 스 니펫을 고려하십시오.

def int_or_default(x, default=0):
    if x.isdigit():
        return int(x)
    else:
        return default

def int_or_default(x, default=0):
    try:
        return int(x)
    except ValueError:
        return default

둘 다 정확해 보입니다. 그러나 그들 중 하나는 아닙니다.

전자는 lbyl을 사용하여 미묘한 차이로 인해 실패합니다. isdigit 그리고 isdecimal; 문자열 "the² 19"로 호출되면 기본값을 올바르게 반환하지 않고 오류가 발생합니다.

나중에 EAFTP를 사용하면 정의상 올바른 처리가 발생합니다. 요구 사항이 필요한 코드이기 때문에 행동 불일치에 대한 범위는 없습니다. ~이다 해당 요구 사항을 주장하는 코드.

lbyl을 사용하는 것은 내부 논리를 가져 와서 복사하는 것을 의미합니다. 모든 콜 사이트. 요구 사항을 하나의 표준 인코딩하는 대신 기능을 호출 할 때마다 무료 기회를 얻을 수 있습니다.

그 eaftp를 주목할 가치가 있습니다 그렇지 않습니다 예외와 Java 코드는 특히 예외를 널리 사용해서는 안됩니다. 올바른 코드 블록에 올바른 작업을 제공하는 것입니다. 예를 들어, 사용 Optional 반환 값은 EAFTP 코드를 작성하는 완벽하게 유효한 방법이며 LBYL보다 정확성을 보장하는 데 훨씬 효과적입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top