IT story

왜 파이썬에서 "최종"절이 필요한가?

hot-time 2020. 4. 4. 11:00
반응형

왜 파이썬에서 "최종"절이 필요한가?


우리가 필요로하는 이유는 확실하지 오전 finallytry...except...finally문. 제 생각에는이 코드 블록

try:
    run_code1()
except TypeError:
    run_code2()
other_code()

이 사용하는 것과 동일합니다 finally:

try:
    run_code1()
except TypeError:
    run_code2()
finally:
    other_code()

뭔가 빠졌습니까?


일찍 돌아 오면 차이가 있습니다.

try:
    run_code1()
except TypeError:
    run_code2()
    return None   # The finally block is run before the method returns
finally:
    other_code()

이것과 비교하십시오 :

try:
    run_code1()
except TypeError:
    run_code2()
    return None   

other_code()  # This doesn't get run if there's an exception.

차이가 발생할 수있는 다른 상황 :

  • except 블록 안에 예외가 발생하는 경우.
  • 예외가 던져 경우 run_code1()만은 아니다 TypeError.
  • continuebreak제어문 과 같은 기타 제어 흐름 문.

당신은 사용할 수 finally있는지 파일이나 자원이 닫히거나에 관계없이 예외가 발생하는지의 출시하기 위해 당신이 예외를 catch하지 않는 경우에도 마찬가지입니다. (또는 특정 예외를 잡지 않으면 )

myfile = open("test.txt", "w")

try:
    myfile.write("the Answer is: ")
    myfile.write(42)   # raises TypeError, which will be propagated to caller
finally:
    myfile.close()     # will be executed before TypeError is propagated

이 예에서는 with명령문을 사용하는 것이 더 좋지만 이러한 종류의 구조는 다른 종류의 리소스에 사용될 수 있습니다.

몇 년 후, 나는 독자들이 재미있는 것으로 남용 할 수 있는 블로그 게시물을 썼습니다 finally.


그것들은 동등하지 않습니다. 마지막으로 코드는 다른 일이 발생하더라도 실행됩니다. 정리 코드를 실행하는 데 유용합니다.


위의 다른 답변에 추가하기 위해 finally절은 무엇이든 관계없이 실행되지만 else예외는 발생하지 않은 경우에만 절이 실행됩니다.

예를 들어, 예외없이 파일에 쓰면 다음이 출력됩니다.

file = open('test.txt', 'w')

try:
    file.write("Testing.")
    print("Writing to file.")
except IOError:
    print("Could not write to file.")
else:
    print("Write successful.")
finally:
    file.close()
    print("File closed.")

산출:

Writing to file.
Write successful.
File closed.

예외가있는 경우 코드는 다음을 출력합니다 (파일을 읽기 전용으로 유지하면 의도적 인 오류가 발생합니다.

file = open('test.txt', 'r')

try:
    file.write("Testing.")
    print("Writing to file.")
except IOError:
    print("Could not write to file.")
else:
    print("Write successful.")
finally:
    file.close()
    print("File closed.")

산출:

Could not write to file.
File closed.

finally예외에 관계없이 절이 실행 되는 것을 볼 수 있습니다 . 도움이 되었기를 바랍니다.


코드 블록은 동일하지 않습니다. finally절은 첫 번째 버전에서는이 경우에 실행되지 않는 반면, run_code1()이외의 예외를 발생 TypeError시키거나 run_code2()예외를 발생 other_code()시키는 경우에도 실행됩니다.


첫 번째 예에서 run_code1()그렇지 않은 예외가 발생하면 어떻게됩니까 TypeError? ... other_code()실행되지 않습니다.

finally:버전 과 비교하십시오 : other_code()예외 발생에 관계없이 실행됩니다.


에서 설명하고있는 바와 같이 문서finally절을 실행해야합니다 청소 작업을 정의하기위한 것입니다 모든 상황을 .

경우 finally존재, 그것은 '정리'핸들러를 지정합니다. try절은 어떤을 포함하여, 실행 exceptelse절. 절에서 예외가 발생하여 처리되지 않으면 예외가 일시적으로 저장됩니다. finally절은 실행됩니다. 저장된 예외가있는 경우 finally조항 끝에서 다시 발생합니다 .

예를 들면 :

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print("division by zero!")
...     else:
...         print("result is", result)
...     finally:
...         print("executing finally clause")
...
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

보시다시피, finally절은 모든 이벤트에서 실행됩니다. TypeError개의 스트링을 분할함으로써 발생은 처리되지 except절과 후 따라서 레이즈 다시 finally절 실행되었다.

실제 응용 프로그램에서 finally 절은 리소스 사용의 성공 여부에 관계없이 외부 리소스 (예 : 파일 또는 네트워크 연결)를 해제하는 데 유용합니다.


finally"정리 조치" 를 정의하기위한 것 입니다. 문은 예외를 처리하지 않더라도 예외를 발생했는지 여부에 관계없이 명령문을 finally떠나기 전에 모든 이벤트에서 실행됩니다 try.

두 번째 @Byers의 예입니다.


마지막으로 주요 작업에 대한 코드를 실행하기 전에 "선택적"코드를 실행하려고 할 때 해당 옵션 코드가 여러 가지 이유로 실패 할 수 있습니다.

다음 예에서는 어떤 종류의 예외 store_some_debug_info가 발생할 수 있는지 정확하게 알지 못합니다 .

우리는 실행할 수 있습니다 :

try:
  store_some_debug_info()
except Exception:
  pass
do_something_really_important() 

그러나 대부분의 정보 제공자는 너무 모호한 예외를 잡는 것에 대해 불평합니다. 또한 우리는 단지 pass오류 만을 선택하기 때문에 except블록은 실제로 가치를 추가하지 않습니다.

try:
  store_some_debug_info()
finally:
  do_something_really_important()     

위의 코드는 첫 번째 코드 블록과 동일한 효과를 갖지만 더 간결합니다.


완벽한 예는 다음과 같습니다.

try:
    #x = Hello + 20
    x = 10 + 20 
except:
    print 'I am in except block'
    x = 20 + 30
else:
    print 'I am in else block'
    x += 1
finally:
    print 'Finally x = %s' %(x)

몇 년 동안 전문적으로 델파이를 사용하면서 마침내 정리 루틴을 보호하는 법을 배웠습니다. 델파이는 try 블록 이전에 생성 된 모든 리소스를 정리하여 메모리 누수를 유발하지 않도록 최종적으로 사용합니다. 이것은 Java, Python 및 Ruby의 작동 방식이기도합니다.

resource = create_resource
try:
  use resource
finally:
  resource.cleanup

시도와 마지막 사이에 수행 한 작업에 관계없이 리소스가 정리됩니다. 또한 실행이 try블록에 도달하지 않으면 정리되지 않습니다 . (예를 들어 create_resource자체적으로 예외가 발생 함) 코드를 "예외 안전"으로 만듭니다.

실제로 finally 블록이 필요한 이유는 모든 언어가 아닙니다. 예외가 스택을 풀 때 정리를 강제하는 소멸자를 자동으로 호출 한 C ++에서. 나는 이것이 최종 언어에 비해 더 깨끗한 코드의 방향으로 한 단계 향상 된 것이라고 생각합니다.

{    
  type object1;
  smart_pointer<type> object1(new type());
} // destructors are automagically called here in LIFO order so no finally required.

try 블록에는 하나의 필수 절인 try 문이 있습니다. except, else 및 finally 절은 선택 사항이며 사용자 기본 설정을 기반으로합니다.

finally : Python이 try 문을 떠나기 전에 프로그램을 종료하더라도 모든 조건에서 finally 블록에서 코드를 실행합니다. 예를 들어, except 또는 else 블록에서 코드를 실행하는 동안 Python에서 오류가 발생하면 프로그램을 중지하기 전에 finally 블록이 계속 실행됩니다.


다음의 Python3 코드를 실행하여 마지막으로 필요한 사항을 확인하십시오.

사례 1 :

count = 0
while True:
    count += 1
    if count > 3:
        break
    else:
        try:
            x = int(input("Enter your lock number here: "))

            if x == 586:
                print("Your lock has unlocked :)")

                break
            else:
                print("Try again!!")

                continue

        except:
            print("Invalid entry!!")
        finally:
            print("Your Attempts: {}".format(count))

CASE2 :

count = 0

while True:
    count += 1
    if count > 3:
        break
    else:
        try:
            x = int(input("Enter your lock number here: "))

            if x == 586:
                print("Your lock has unlocked :)")

                break
            else:
                print("Try again!!")

                continue

        except:
            print("Invalid entry!!")

        print("Your Attempts: {}".format(count))

매번 다음 입력을 시도하십시오.

  1. 임의의 정수
  2. 올바른 코드는 586입니다 (이걸 시도하면 답을 얻을 수 있습니다)
  3. 임의의 문자열

** 파이썬 학습 초기 단계.

참고 URL : https://stackoverflow.com/questions/11551996/why-do-we-need-the-finally-clause-in-python

반응형