논리 연산자로 Try / Catch를 사용하거나 반대하는 주장


36

Try-Catch 블록을 논리 연산자로 사용하는 회사 앱에서 멋진 코드를 발견했습니다.
즉, "이 오류가 발생하면이 코드를 수행하십시오. 그러나이 오류가 발생하면이 3 번째 작업을 수행하십시오"라는 의미입니다.
표시되는 "else"문으로 "Finally"를 사용합니다.
나는 이것이 본질적으로 잘못되었다는 것을 알고 있지만, 싸움을 선택하기 전에 나는 잘 생각하는 논쟁을 기대하고있었습니다.
이런 식으로 Try-Catch 사용에 대한 주장이 있다면 알려주세요.

궁금한 사람은 언어가 C #이고 문제의 코드가 약 30 줄 이상이며 특정 예외를 찾고 있는데 모든 예외를 처리하지는 않습니다.


13
나는 이 관행 에 반대 하는 주장 만 가지고 있으며 , 이미 나쁜 생각이라고 확신하기 때문에 게시하지 않아도됩니다.
FrustratedWithFormsDesigner

15
@FrustratedWIthFormsDesigner : 나쁜 추론입니다. 확신이없는 사람들은 어떻습니까? 내가 왜 그것이 틀렸다는 것을 "왜"말할 수 없기 때문에 내가 구체적으로 이유를 묻는 실제 질문은 어떻습니까?
James P. Wright

3
내 의견은 문제의 코드가 실제로하는 일에 크게 달려 있습니다. 미리 점검 할 수없는 것들이 있습니다 (또는 많은 파일 조작과 같이 시도 할 때 레이스 조건을 허용합니다-점검과 조작 사이의 지연에서 파일에 발생할 수있는 모든 일) try. 일반적으로 예외를 보증하는 모든 예외적 인 사례가이 특정 사례에서 치명적일 필요는 없습니다. 따라서 예외를 사용하지 않고 더 간단하고 동일하거나 더 강력한 방법으로 할 수 있습니까?

11
"finally"블록은 예외 발생 여부에 관계없이 항상 이전 코드 이후에 실행되기 때문에 "finally"블록을 "else"로 사용하지 않기를 바랍니다.
jimreed

2
그들은 어떤 언어를 사용하고 있습니까? 표준 라이브러리가 일상적으로 예외를 던지는 OCaml에서 완벽하게 작동합니다. 예외 처리는 매우 저렴합니다. 그러나 CLI 또는 JVM에서는 그렇게 효율적이지 않습니다.
SK-logic

답변:


50

예외 처리는 흐름 제어를 처리 하는 비싼 방법 인 경향이 있습니다 (확실히 C # 및 Java의 경우).

예외 객체가 생성 될 때 런타임은 많은 작업을 수행합니다. 스택 추적을 함께 가져와 예외가 처리되는 위치 등을 파악합니다.

흐름 제어 명령문을 흐름 제어에 사용하는 경우 확장 할 필요가없는 메모리 및 CPU 자원의 모든 비용.

또한 의미 상 문제가 있습니다. 예외적 인 상황은 예외이며 정상적인 흐름 제어는 예외입니다. 예상치 못한 / 예외 상황을 처리하기 위해 예외 처리를 사용해야합니다. 그렇지 않으면 포착되지 않은 예외가 훨씬 적기 때문에 정상적인 프로그램 흐름이 아닙니다.

이 두 가지 외에도 코드를 읽는 다른 사람들의 문제가 있습니다. 이러한 방식으로 예외를 사용하는 것은 대부분의 프로그래머가 기대하는 것이 아니므로 가독성과 코드 이해가 어려워집니다. "예외"를 볼 때, 나쁜 일이 발생했거나 정상적으로 일어나지 않아야 할 일이 있다고 생각합니다. 따라서 이러한 방식으로 예외를 사용하는 것은 혼란 스럽습니다.


1
성능에 대한 좋은 점은 플랫폼의 특성에 따라 다릅니다.
FrustratedWithFormsDesigner

4
그것이 유일한 단점이라면, 고마워-성능이 중요한 경로를 제외하고는 더 나은 코드를 사면 언젠가는 성능을 포기할 것입니다. -결정적인).

5
@delnan-아니요, 유일한 단점은 아닙니다.
Oded

2
확인되지 않은 단어 외에는 귀하의 게시물에 동의합니다. 코드에 예외가 발생하는 시간이 있습니다. 대부분은 DB 또는 서비스 호출의 연결 실패 또는 관리되지 않는 코드를 처리 할 때와 같이 예측 가능해야합니다. 통제 할 수없는 문제를 잡아서 처리합니다. 그러나 코드 내에서 피할 수있는 예외를 기반으로 흐름 제어를해서는 안된다는 데 동의합니다.
SoylentGray

4
"예외 처리는 흐름 제어를 처리하는 데 비용이 많이 드는 경향이 있습니다". 파이썬에 대한 거짓.
S.Lott

17

Try-Catch 블록을 논리 연산자로 사용하는 회사 앱에서 멋진 코드를 발견했습니다. 즉, "이 오류가 발생하면이 코드를 수행하십시오. 그러나이 오류가 발생하면이 3 번째 작업을 수행하십시오"라는 의미입니다. 표시되는 "else"문으로 "Finally"를 사용합니다. 나는 이것이 본질적으로 잘못되었음을 알고있다 ...

어떻게 알았어? 나는 모든 종류의 "지식"을 포기했으며 이제는 가장 간단한 코드가 최고라고 믿습니다. 구문 분석에 실패하면 문자열을 Optional로 변환한다고 가정합니다. 아무 문제가 없습니다 :

try { 
    return Optional.of(Long.valueOf(s)); 
} catch (NumberFormatException) { 
    return Optional.empty(); 
}

나는 "예외가 예외입니다"라는 일반적인 해석에 완전히 동의하지 않습니다. 함수가 사용 가능한 값을 반환 할 수 없거나 메서드가 사후 조건을 충족 할 수없는 경우 예외를 발생시킵니다. 성능 문제가 입증 될 때까지 이러한 예외가 얼마나 자주 발생하는지는 중요하지 않습니다.

예외는 정상 흐름에서 오류 처리를 분리하여 코드를 단순화합니다. 가능한 가장 간단한 코드를 작성하고 try-catch를 사용하거나 예외를 던지는 것이 더 쉬운 경우 그렇게하십시오.

예외는 코드를 통한 경로 수를 줄여 테스트를 단순화합니다. 분기가없는 함수는 예외를 완료하거나 발생시킵니다. if오류 코드를 확인하기 위해 여러 명령문이 있는 함수 에는 가능한 많은 경로가 있습니다. 조건 중 하나를 잘못 이해하거나 하나를 완전히 잊어 버리면 일부 오류 조건이 무시됩니다.


4
나는 이것이 실제로 꽤 좋은 주장이라고 생각합니다. 코드는 깨끗하고 간결하며 수행중인 작업에 적합합니다. 이것은 실제로 내가보고있는 코드에서 발생하는 것과 유사하며 훨씬 복잡하고 중첩되어 있으며 30 줄 이상의 코드에 걸쳐 있습니다.
James P. Wright

@ 제임스 : 작은 방법을 추출하면 코드가 좋을 것 같습니다.
kevin cline

1
Java가 실제로 C #의 TryParse와 같은 것을 사용할 수 있다고 주장 할 수 있습니다. C #에서 해당 코드는입니다 int i; if(long.TryParse(s, out i)) return i; else return null;. 문자열을 구문 분석 할 수없는 경우 TryParse는 false를 반환합니다. 구문 분석 할 수 있으면 출력 인수를 구문 분석 결과로 설정하고 true를 리턴합니다. 내부적으로 TryParse에서도 예외가 발생하지 않으며, 특히 .NET과 같이 프로그래머 오류를 의미하는 형식의 예외는 FormatException항상 표시되지 않습니다.
Kevin Cathcart

1
@ 케빈 캐스 카트,하지만 왜 더 나은가요? NumberFormatException을 잡는 코드가 나에게 훨씬 더 명백한 다음 TryParse의 결과를 null로 확인합니다.
Winston Ewert

1
@ChrisMiskowiec, 나는 당신이 어느 것을 더 명확하게 발견했는지는 당신이 익숙한 것의 문제라고 생각합니다. 나는 예외를 따라 가기 쉽고 마술 값을 확인하는 것을 발견했습니다. 그러나 그것은 모두 주관적입니다. 객관적으로, 우리는 예외를 선호해야한다고 생각합니다. 예외는 버그를 숨기는 기본값 (아무것도 일어나지 않은 것처럼 계속됨)이 아니라 정상적인 기본값 (프로그램 충돌)이 있기 때문입니다. .NET이 예외적으로 제대로 수행되지 않는 것은 사실입니다. 그러나 이는 예외의 특성이 아니라 .NET의 설계 결과입니다. .NET에 있다면 그렇게해야합니다. 그러나 원칙적으로 예외가 더 낫습니다.
Winston Ewert

12

예외를 사용하여 제어 흐름을 수행하면 디버그 및 유지 관리 작업이 매우 어렵습니다.

본질적으로 예외는 프로그램의 정상적인 제어 흐름을 변경하는 메커니즘으로 설계되었습니다. 비정상적인 활동을 수행하고 비정상적인 부작용을 유발하여 덜 복잡하게 처리 할 수없는 특히 긴박한 바인딩에서 벗어날 수있는 방법으로 설계되었습니다. 방법. 예외는 예외입니다. 즉, 작업중인 특정 환경에 따라 정기적 인 제어 흐름에 예외를 사용하면 다음이 발생할 수 있습니다.

  • 비 효율성 예외에 필요한 상대적으로 어려운 컨텍스트 변경을 안전하게 수행하기 위해 환경을 뛰어 넘어야하는 추가적인 후프에는 계측 및 리소스가 필요합니다.

  • 디버그 난이도 예외가 발생하면 때때로 유용한 정보 (프로그램을 디버깅하려고 할 때)가 창 밖으로 나옵니다. 런타임 동작 이해와 관련된 프로그램 상태 또는 기록을 잃을 수 있습니다.

  • 유지 관리 문제 예외 흐름을 통해 실행 흐름을 따르기가 어렵습니다. 그 외에도 블랙 박스 타입 코드에서 예외가 발생하여 예외를 던질 때 이해하기 어려운 방식으로 작동하지 않을 수 있습니다.

  • 열악한 설계 결정 이러한 방식으로 구축 된 프로그램은 대부분의 경우 문제를 우아하게 해결하는 데 도움이되지 않는 마음가짐을 장려합니다. 최종 프로그램의 복잡성으로 인해 프로그래머는 실행을 완전히 이해하지 못하고 결정을 내릴 수있어 장기적인 비용으로 단기적으로 개선 할 수 있습니다.


10

이 패턴이 여러 번 사용되는 것을 보았습니다.

두 가지 주요 문제가 있습니다.

  • 매우 비쌉니다 (예외 객체의 인스턴스화, 호출 스택 수집 등). 일부 컴파일러는 실제로 그것을 최적화 할 수는 있지만 예외는 그러한 용도로 사용되지 않으므로 사람들이 최적화 할 것으로 기대할 수 없기 때문에이 경우에는 그렇게 생각하지 않습니다.
  • 제어 흐름에 예외를 사용하는 것은 실제로 a와 매우 유사합니다 goto. 점프는 여러 가지 이유로 해로운 것으로 간주됩니다. 모든 대안에 상당한 단점이있는 경우 사용해야합니다. 사실, 내 모든 코드에서 점프가 분명히 가장 좋은 솔루션 인 두 가지 경우 만 기억합니다.

2
if / else도 점프로 간주됩니다. 차이점은 특정 지점에서만 발생할 수있는 점프이며 훨씬 더 쉽게 읽을 수 있으며 레이블의 이름에 대해 걱정할 필요가 없다는 것입니다 (try / catch 와도 관련이 없음) 그러나 goto와 비교). 그러나 "이것은 나쁜 점프입니다"라고 말하는 것만으로도 그렇지 않은 경우에는 그렇지 않은 경우가 있습니다.
jsternberg

1
@jsternbarg : 그렇습니다 ./else가 실제로 기계 수준에서 점프하도록 컴파일되었지만 언어 수준에서 점프 대상은 다음 명령문이지만 루프의 경우 현재 명령문입니다. 나는 그것이 점프보다 더 많은 단계라고 주장한다;)
back2dos

9

때로는 예외가 가장 빠릅니다. Java 에서조차도 제어 구조를 사용하는 것보다 null 객체 예외가 더 빠른 경우를 보았습니다 (현재 연구를 인용 할 수 없으므로 나를 믿어야합니다). Java가 실제로 시간이 걸리고 네이티브 클래스 (적어도 부분적으로 캐시 된 것처럼 보임)를 사용하는 대신 사용자 정의 예외 클래스의 스택 추적을 채워야 할 때 문제가 발생합니다. 일방적으로 빠르거나 느리다는 말을하기 전에 벤치마킹하는 것이 좋습니다.

파이썬에서는 더 빠를뿐만 아니라 예외를 일으킨 다음 오류를 처리 할 수있는 일을하는 것이 훨씬 더 정확합니다. 예, 타입 시스템을 적용 할 수는 있지만 언어 철학에 어긋납니다. 대신 단순히 메소드를 호출하고 결과를 잡아야합니다! (파일이 쓰기 가능한지 테스트하는 것은 비슷합니다. 파일에 쓰고 시도해보십시오).

PHP + MySQL에 테이블이 있는지 여부를 파악하는 것보다 쿼리 테이블과 같은 어리석은 일이 더 빠르는 시간을 보았습니다 ( 이 벤치 마크에 대한 질문 은 실제로 부정적인 투표를 가진 유일한 대답입니다) .

그러나 예외 사용은 몇 가지 이유로 제한되어야합니다.

  1. 중첩 된 예외의 우연한 삼키기. 이것이 중요하다. 다른 사람이 처리하려고하는 깊게 중첩 된 예외를 발견하면 동료 프로그래머 (아마도 당신!)를 발로 쏜 것입니다.
  2. 테스트는 분명하지 않습니다. 예외가있는 코드 블록에는 몇 가지 문제가있을 수 있습니다. 반면에 부울은 이론적으로 디버그하기가 성가 시지만 일반적으로 그렇지 않습니다. try...catch제어 흐름 준수자가 일반적으로 (내 경험상) "시도 블록의 코드 최소화"철학을 따르지 않기 때문에 특히 그렇습니다 .
  3. else if블록을 허용하지 않습니다 . 충분히 말했다 (그리고 누군가가 "그러나 다른 예외 클래스를 사용할 수있다"고 반대한다면, 나의 대답은 "방에 가서 당신이 한 말에 대해 생각할 때까지 나오지 않는 것입니다.")
  4. 문법적으로 오해의 소지가 있습니다. Exception( try...catch제어 흐름 철학 을 따르지 않는 것처럼) 세계의 다른 사람들 에게 무언가는 불안정한 (아마도 회복 가능하지만) 상태에 들어갔다는 것을 의미합니다. 불안정한 상태는 나쁘고 실제로 피할 수있는 예외가있는 경우 밤에 우리 모두를 지켜야합니다 (실제로 나를 놀라게하고 거짓말하지 않습니다).
  5. 일반적인 코딩 스타일과 호환되지 않습니다. 우리의 코드와 UI를 통한 우리의 일은 세상을 가능한 한 분명하게 만드는 것입니다. try...catch제어 흐름은 일반적으로 모범 사례로 간주되는 것과 반대됩니다. 이것은 프로젝트를 처음 접하는 사람이 프로젝트를 배우는 데 더 많은 시간이 걸리는 것을 의미합니다. 이는 절대적으로 이득을 얻지 못하는 인력 시간의 증가를 의미합니다.
  6. 이것은 종종 코드 복제로 이어집니다. 마지막으로 블록이 꼭 필요한 것은 아니지만 인터럽트 된 try 블록에 의해 열려있는 매달린 포인터를 모두 해결해야합니다. 블록을 시도하십시오. 이것은 당신이 할 수 있음을 의미합니다 try{ obj.openSomething(); /*something which causes exception*/ obj.doStuff(); obj.closeSomething();}catch(Exception e){obj.closeSomething();}. 보다 전통적인 if...else시나리오에서는 closeSomething()복사 및 붙여 넣기 작업이 될 가능성이 적습니다 (다시 개인적인 경험). (이 특별한 주장은 실제 철학 자체보다 내가 만난 사람들과 더 관련이있다).

AFAIK, # 6은 다른 모든 최신 언어와 달리 클로저 나 스택 기반 리소스 관리가없는 Java에서만 문제입니다. 예외 사용에 내재 된 문제는 아닙니다.
케빈 클라인

4와 5는 나에게 같은 점인 것 같습니다. 귀하의 언어가 파이썬 인 경우 3-6은 적용되지 않습니다. 1과 2는 잠재적 인 문제이지만 try 블록의 코드를 최소화하여 처리한다고 생각합니다.
Winston Ewert

1
@Winston 동의하지 않습니다. 1과 2는 더 나은 코딩 표준으로 줄어든 반면, 잠재적 인 오류를 피하는 것이 더 나을 수 없는지 궁금해하는 주요 문제입니다. 언어가 Python 인 경우 3이 적용됩니다. 4-5는 파이썬에도 지원할 수 있지만 꼭 그럴 필요는 없습니다. 4와 5는 매우 다른 포인트입니다. 잘못된 코드는 "정지 버튼"으로 차량을 시작하기 위해 트리거 이름을 지정하는 것과 같은 작업을 수행 할 수 있습니다. 다른 한편으로,이 말은 C의 모든 블록 들여 쓰기를 피하는 것과 유사 할 수도있다.
cwallenpoole

3) 파이썬에는 예외에 대한 else 블록이 있습니다. 일반적으로 1과 2에 발생하는 문제를 피하는 데 큰 도움이됩니다.
Winston Ewert

1
분명히하기 위해 예외를 사용하는 것을 옹호하지는 않습니다. 일반적인 흐름 제어 메커니즘입니다. 아무리 사소한 종류의 "실패"모드에 대해서는 예외를 던지는 것을 옹호합니다. 예외 처리 버전이 더 깨끗하고 버그를 숨길 가능성이 적고 반환 값 확인 버전이라고 생각합니다. 이상적으로는 중첩 된 오류를 잡기가 더 어려워지는 언어를 원합니다.
Winston Ewert

4

내 주요 주장은 논리에 try / catch를 사용하면 논리 흐름이 중단된다는 것입니다. 비논리적 구조를 통한 "논리적"은 반 직관적이고 혼란 스럽다. 나는 논리를 "if Condition then A else B"로 읽는 데 익숙합니다. "A catch 시도 후 B 실행"과 같은 문장을 읽는 것이 이상하게 느껴집니다. 만약 문장 A이 단순한 할당 이라면 그것은 더 이상 할 것이다. 만약 condition거짓 이라면 예외를 강제하기 위해 여분의 코드가 필요하다 if.


2

글쎄, 에티켓 문제는, "그들과 논쟁을 시작하기"전에, "왜 그들이 다른 모든 곳에서 예외 처리를 사용 하는가?"라고 묻습니다.

몇 가지 가능성이 있습니다.

  1. 그들은 무능하다
  2. 그들이 한 일에 대해 완벽하게 유효한 이유가 있으며, 첫눈에 나타나지 않을 수도 있습니다.
  3. 때로는 맛의 문제이며 복잡한 프로그램 흐름을 단순화 할 수 있습니다.
  4. 아직 아무도 변하지 않은 것은 과거의 유물이며 누군가가 그것을하면 행복 할 것입니다.

...이 모든 것이 똑같이 가능하다고 생각합니다. 그냥 물어보세요.


1

Catch는 예외 처리에만 사용해야합니다. 더욱 구체적으로 예외 처리. 시도 캐치는 예상되는 예외 만 잡아야하며, 그렇지 않은 경우에는 제대로 구성되지 않습니다. catch all try catch를 사용해야하는 경우 무언가 잘못한 것일 수 있습니다.

편집하다:

이유 : try catch를 조건부 연산자로 사용하면 REAL 예외를 어떻게 처리 할 수 ​​있습니까?


2
OP는 이유 / 인수를 요구하고 있습니다. 제공하지 않았습니다.
Oded

"조건부 연산자로 try catch를 사용하면 REAL 예외를 어떻게 처리 할 수 ​​있을까요?" - catch"실제가 아닌"예외 를 포착하는 것과 다른 절 에서 이러한 실제 예외를 포착함으로써 ?

@delnan-감사합니다! 당신은 내가 만들려고하는 요점을 증명했습니다. 만약 당신이 내 이유와 오데드 둘 다에 대해 당신이 방금 말한 것에 대답했다면, 나는 단지 원인을 말하는 것을 그만 둘 것입니다. 그는 단지 고집을 부리고있는 이유를 찾지 않고 있으며, 나는 시간을 고집스럽게 낭비하지 않습니다.
AJC

여기에 나열된 몇 가지 주장의 결함을 지적했기 때문에 당신은 나를 studdborn이라고 부릅니다. 여기에 언급 된 다른 요점들에 대해 아무 말도하지 않습니다. 나는 흐름 제어에 예외를 사용하는 팬이 아닙니다 (세부 사항없이 아무것도 정죄하지 않기 때문에 OP에 의한 정교화에 대한 쿼리), 나는 단지 악마의 옹호자를 연기하고 있습니다.

1
try-catch를 조건부 연산자로 사용하면 "실제"예외를 포착하기 위해 작동하지 않습니다.
Winston Ewert

1

예외적 인 상황이 발생한 경우는 예외입니다. 프로그램이 정기적 인 워크 플로우에 따라 작동합니까?


1
그런데 왜? 문제의 요점은 예외가 왜 그에게만 적합한 지 (또는 왜 그렇지 않은지)입니다.
Winston Ewert

항상 "예외적"인 것은 아닙니다. 예를 들어 해시 테이블에서 키를 찾지 못하는 것은 그다지 예외적 인 것은 아니지만 OCaml 라이브러리는 이러한 경우 예외를 발생시키는 경향이 있습니다. 예외 처리가 매우 저렴합니다.
SK-logic

1
-1 : tautological statement
쌀가루 쿠키

1

예외를 사용해야하는 이유 :

  1. 예외적 인 상황을 잊어 버린 경우 프로그램이 종료되고 스택 추적에서 정확한 이유를 알려줍니다. 예외 상황에 대한 반환 값을 처리하는 것을 잊어 버린 경우 프로그램이 얼마나 멀리 잘못된 동작을하는지 알 수 없습니다.
  2. 리턴 값 사용은 리턴 할 수있는 센티넬 값이있는 경우에만 작동합니다. 가능한 모든 반환 값이 이미 유효한 경우 어떻게해야합니까?
  3. 예외는 어떤 일이 발생했는지에 대한 추가 정보를 제공하며 유용 할 수 있습니다.

예외를 사용하지 않는 이유 :

  1. 많은 언어가 예외를 빠르게 만들도록 설계되지 않았습니다.
  2. 스택 위로 여러 레이어를 이동하는 예외는 깨어날 때 일관성이없는 상태를 유지할 수 있습니다

결국 :

목표는 진행 상황을 전달하는 코드를 작성하는 것입니다. 코드가 수행하는 작업에 따라 예외가 도움이 될 수 있습니다. 사전 참조의 KeyError에 대한 파이썬의 try / catch는 (언어를 아는 한) 동일한 KeyError에 대한 try / catch는 5 개의 함수 레이어가 떨어져있는 위험합니다.


0

특정 상황에서 try-> catch를 흐름 제어로 사용합니다. 기본 논리가 실패한 것에 의존하지만 예외를 던지고 끝내고 싶지 않다면 try-> catch 블록의 목적입니다. 나는 모니터되지 않은 많은 서버 측 유닉스 스크립트를 작성하고, 실패하지 않는 것이 예쁘게 실패하는 것보다 훨씬 중요합니다.

따라서 계획 A를 시도 하고 계획 A가 사망 하면 계획 B를 잡아서 실행하십시오. 계획 B가 실패하면 마지막 으로 계획 C를 시작하여 실패한 서비스 중 하나를 A 또는 B 또는 페이지에서 수정하십시오 나를.


0

언어와 사용중인 구현에 따라 다릅니다. C ++의 표준은 예외적 인 이벤트를 위해 예외를 저장해야한다는 것입니다. 반면에 파이썬에서 지침 중 하나는 " 권한보다 용서를 구하는 것이 더 쉽다 "는 것이므로 프로그램 논리에 try / except 블록을 통합하는 것이 좋습니다.


"C ++의 표준은 예외적 인 이벤트를 위해 예외를 저장해야한다는 것입니다." 이것은 말도 안됩니다. 언어를 발명 한 사람조차도 당신의 의견에 동의하지 않습니다 .
arayq2

-1

나쁜 습관이지만 파이썬에서 때때로합니다. 파일이 있는지 확인하는 대신 파일을 삭제하고 삭제하기 만하면됩니다. 그것이 예외를 던지면 나는 거기에 없다는 것을 알고 계속 나아갑니다. <== (다른 사용자가 파일을 소유 한 경우에는 반드시 사실 일 필요는 없지만, 사용자 홈 디렉토리에서 파일을 수행하므로이 문제가 발생하지 않습니다).

그럼에도 불구하고, 그것은 나쁜 습관입니다.


3
이 예에서 "도약하기 전에보기"대신 예외를 사용하는 것이 실제로 좋은 아이디어입니다. 경쟁 조건을 피합니다. 파일 가용성 (존재, 권한, 잠기지 않음)을 확인한다고해서 나중에 오피 코드가 몇 개라도된다고해서 나중에 파일을 열 수 있기 때문에 액세스 (열기, 삭제, 이동, 잠금 등)가 성공한 것은 아닙니다. 사이에 변경 (삭제, 이동, 권한 변경)

파일이 존재하지 않기 때문에 파이썬이 예외를 던지면 delnan이 설명한 것처럼 나쁜 습관을 장려하는 것 같습니다.
당 Johansson

@delnan : 사실이지만 IMHO가 그러한 경쟁 조건에 처할 가능성이 있다면 디자인을 다시 생각해야합니다. 이 경우 시스템에 대한 우려의 분리가 분명히 부족합니다. 그렇게해야하는 이유가 충분하지 않으면 액세스를 통합하거나 동일한 데이터베이스에서 트랜잭션을 수행하려는 여러 클라이언트를 처리하기 위해 적절한 데이터베이스를 사용해야합니다.
back2dos

1
이것은 나쁜 습관이 아닙니다. 파이썬에서 권장되는 스타일입니다.
Winston Ewert

@ back2dos, 데이터베이스 / 파일 시스템의 다른 사용자와 같은 외부 리소스를 다룰 때이를 막을 수 있습니까?
Winston Ewert

-1

애플이 정의한 방식이 마음에 듭니다. 예외는 프로그래머 오류와 치명적인 런타임 오류에 대해서만 적용됩니다. 그렇지 않으면 오류 코드를 사용하십시오. "프로그래머 오류입니까?"라고 생각하면서 언제 사용할지 결정하는 데 도움이됩니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.