1. Python의 이념 & 반복문(1) - while문 > 개발강좌

개발강좌

프로그램 강좌 :
1. 유창화님의 썸네일, 정규표현식, 이미지관련 강좌
2. Sphinx 검색엔진을 이용한 도로명 주소 검색 시스템 구축

1. Python의 이념 & 반복문(1) - while문 정보

그누보드5 1. Python의 이념 & 반복문(1) - while문

본문

1970214704_1655424430.8366.png

안녕하세요?

<그누보드 개발자를 위한 Python 강좌>의 첫 번째 강좌로 Python의 문법적 특징 내지 이념을 알아본 후,

반복문 중 While문을 다뤄보고자 합니다.

 

Python은 다음과 같은 이념을 기반으로 하고 있습니다.

 

  • 아름다운 것이 추한 것보다 낫다. (Beautiful is better than ugly.)
  • 명시적인 것이 암시적인 것보다 낫다. (Explicit is better than implicit.)
  • 간결한 것이 복잡한 것보다 낫다. (Simple is better than complex.)

 

즉 Python의 문법적 이념은 "모든 문제에는 아름답고 명시적이며 간결한 하나의 답이 있다"는 것으로 귀결됩니다.

이러한 이념의 옳고 그름을 떠나서 그 이념적 특성 때문에,

Python으로 작성된 코드는 Perl과 달리 '수렴' 진화하는 경향이 있으며,

타인이 작성한 스크립트를 읽을 때 상대적으로 가독성과 이해도가 좋은 편입니다.

다만 이와 같은 특징 때문에 Python의 문법이 다른 언어에 비하여 엄격하고 까다롭다는 지적을 받기도 합니다.

 

Python의 위와 같은 문법적 특징이 잘 나타나는 것이 바로 반복문입니다.

Python은 다른 언어에서 흔히 볼 수 있는 loop문 또는 do~while문이 없고,

오직 while문과 for문이 있을 뿐입니다.

게다가 Python의 for문은 PHP의 foreach문에 해당하며,

C나 Java를 비롯한 대다수의 언어에서 볼 수 있는 전형적인 형식의 for(;;)문이 존재하지 않는 이유 또한 위와 같은 Python의 기본이념과 관련이 깊습니다.

즉 반복을 하여야 할 사안에 대하여 단 하나의 해결책을 찾아야 하는 것입니다.

 

Python의 while문은 다른 언어와 유사하여 특별히 다룰 쟁점이 많지는 않지만,

다른 언어 개발자가 Python에 입문할 때 유의하여 할 점을 위주로 설명드리겠습니다.

 

 

1. while문의 기본형식

기본적으로 Python의 while문은 다른 언어의 while문과 유사합니다. 

while문은 조건식이 True일 때에는 while문 안의 코드를 반복하며,

False일 때에는 그 반복을 종료합니다.

while문을 도식화하여 표현하면 다음과 같습니다.


초기식
while 조건식:
    반복할 코드
    변화식

 

예컨대 다음과 같은 방법으로 print()문을 n회 작성하여야 할 것을, 

간단히 반복문으로 해결할 수 있습니다.


n = 1
while n <= 3:
    print(f'유비가 제갈량의 집에 {n}번째 방문합니다.')
    n += 1
print('드디어 제갈량을 만났습니다!')

 

다음과 같은 방법으로 한 줄짜리 while문을 작성할 수도 있습니다.

다만 대표적인 Python 코드 작성 가이드인 PEP 8에 따르면 이러한 방법은 권장되지 않습니다.

참고 : https://peps.python.org/pep-0008/


n = 1
while n <= 10: print(f'나무를 {n}번째 찍었습니다'); n += 1;
print('나무가 넘어갔습니다!')

 

 

2. 어느 경우에 while문과 for문을 사용하여야 되는가?

Python을 처음 접하는 분들, 특히 코딩에 입문한 분들께서 종종 하는 질문 중 하나는,

"반복문을 사용할 때 어느 경우에 while문을, 어느 경우에 for문을 사용해야 되는가요?"입니다.

위 질문에 대하여 일률적으로 답하기는 어렵지만,

while문은 반복할 횟수가 정해지지 않은 경우(ex. 무한루프)에 주로 사용한다고 볼 수 있는 반면,

for문은 반복할 횟수가 정해진 경우에 주로 이용한다고 볼 수 있습니다.

특히 Python의 for문은 다른 언어의 foreach문에 해당하기 때문에,

for문은 반복 가능한 객체를 for~in문을 사용하여 반복하는 경우에 주로 사용됩니다.

 

Python에는 다른 언어의 for(;;)문에 해당하는 구문은 없지만,

for문을 range()와 함께 사용하는 방식을 활용하여 이를 대신하도록 하고 있습니다.

단순히 n회 반복을 하여야 하는 경우에는 for문과 range()를 함께 사용하면,

변수 하나를 덜 선언할 수 있기 때문에 for문이 while문보다 효율적이라고 볼 수 있습니다.

참고로 Python3에서는 range() 함수가 반환하는 객체는 list나 tuple이 아닌 range 객체인데,

이는 list나 tuple보다 메모리를 효율적으로 사용할 수 있다는 장점이 있습니다.

참고 : https://docs.python.org/3/library/stdtypes.html#range


for _ in range(5)
    print('젤소미나 : 잠파노가 왔어요!')

 


cnt = 1
while cnt <= 5:
    print('젤소미나 : 잠파노가 왔어요!')
    cnt += 1

 

결론적으로 무한루프 등 반복횟수가 불특정된 경우에는 while문을,

반복횟수가 특정되어 있거나, 반복 가능한 객체를 반복하는 경우에는 for문을 사용하는 것이 보편적입니다.

 

 

3. while문을 제어하는 break 및 continue

다른 언어와 마찬가지로 Python에서 while문을 제어하는 명령어로는 break와 continue가 있습니다.

그런데 while문 안의 try~except문에 break나 continue를 사용하면, break나 continue를 하더라도 finally의 코드가 실행되는 특성이 있습니다.

이를 간단한 예제를 통하여 살펴보겠습니다.


n = 0
while True:
    n += 1
    if n > 10:
        break
    print(n)

 


n = 0
while True:
    n += 1
    try:
        if n > 10:
            break
    except:
        pass
    finally:
        print(n)

 

두 코드는 유사해보이지만 첫 번째 코드는 1~10을 출력하는 반면,

두 번째 코드는 1~11을 출력합니다.

이러한 현상에 대하여 Python 공식문서에서는 아래와 같이 언급하고 있습니다.

"If the try statement reaches a break, continue or return statement, the finally clause will execute just prior to the break, continue or return statement’s execution."

출처 : https://docs.python.org/3/tutorial/errors.html

위와 같은 특성 때문에 작성자가 의도한 것과는 다른 결과가 발생할 가능성이 있다는 점에서,

가급적이면 break 등을 사용하지 않는 것이 보다 바람직한 코딩 컨벤션이라 생각됩니다.

 

 

4. do~while문을 대체하는 방법

C언어나 Java에서 존재하는 do~while문은 우선 코드를 1회 실행한 후 조건식의 참거짓 여부를 나중에 판단하는 구문으로서,

최소 1회 이상 코드를 실행한다는 점에서 그렇지 않은 while문과 차이가 있습니다.

Python에는 do~while문이 존재하지 않으나, 아래와 같은 방법으로 구현할 수 있습니다. 




while True:
    반복할 코드
    if 종료할 조건:
        break

 



switch = True
while switch or 반복할 조건:
    switch = False
    반복할 코드

 

앞서 설명드린 이유로 try~except문을 사용할 때의 혼동 가능성 때문에,

break를 사용한 첫 번째 코드보다는 이를 사용하지 않은 두 번째 코드가 바람직하다고 생각됩니다.

 

 

5. while~else문

Java 등 언어와는 달리 Python에서는 while~else라는 특유의 구문이 있습니다.

위 구문은 (1) while문의 조건식이 False인 경우, (2) while문에 진입하지 않은 경우, (3) while문이 정상적으로 종료된 경우, else문을 실행합니다.

아래 스크립트의 경우 'else문을 실행합니다'을 출력합니다.


x = 1
while x > 5:
    print('while문을 실행합니다')
else:
    print('else문을 실행합니다')

 

다만 break를 통하여 while문을 빠져나온 경우 else문을 실행하지 않습니다.

따라서 아래 스크립트는 아무 것도 출력하지 않습니다.


x = 1
while True:
    x += 1
    if x > 5:
        break
else:
    print(x)

 

아래 스크립트는 while~else문을 이용한 매우 심플한 GET Flooding 방식의 DDoS 예제로서,

6월 내내 공격을 수행한 경우에 else문이 실행됩니다.

(물론 정상적인 홈페이지가 이러한 공격을 허용하는 경우는 존재하지 않을 것으로 생각됩니다.)


import requests
from datetime import datetime
 
url = 'foo.kr'
while datetime.now().month == 6: # 현재 시간이 6월인 경우 반복합니다.
    rsp = requests.Session.get(url) # url에 GET 요청을 합니다.
    if rsp != 200: # GET 요청에 대해 200 응답이 없으면 중단합니다.
        break
else:
    print(f'6월 내내 {url}을 공격하였습니다!')

 

 

6. while문을 이용한 무한루프

상용화된 프로그램 중에서 무한루프 개념을 사용하지 않는 프로그램은 거의 없을 정도로, 

무한루프는 매우 빈번하게 사용되는 구문입니다.

Python의 무한루프는 다른 언어와 마찬가지로 주로 while문을 사용하여 처리합니다.

물론 다음과 같은 방법으로 for문으로도 무한루프를 생성할 수는 있습니다.


for _ in iter(int, 1):

 

예제로 무한루프를 활용하여 60초 간격으로 스크린샷을 캡쳐한 후,

캡쳐시간을 파일명으로 하여 PNG 파일로 저장하는 코드를 작성하였습니다.


import pyscreenshot, time
from datetime import datetime
 
while True:
    timestamp = datetime.now().strftime('%Y%m%d-%H%M%S') # 현재 시간을 구합니다.
    im = pyscreenshot.grab() # 화면을 캡쳐합니다.
    im.save(f'screenshot_{timestamp}.png') # 캡쳐한 결과를 파일로 저장합니다.
    time.sleep(60) # 60초 동안 sleep 합니다.

 

 

7. 강좌를 마무리하며

지금까지 살펴본 바와 같이 Python의 while문은 다른 언어의 while문과 유사하면서도,

몇 가지 측면에서는 상이한 점이 있습니다.

다음 강좌에서는 Python의 고유한 문법이 더욱 잘 반영되어 있는 for문에 대하여 다뤄보겠습니다.

그럼 즐거운 주말 되시기를 기원합니다 ^^

추천
15

댓글 16개

굿입니다. ( ^ _______ ~ ) ==b


PS. 아래 구문에서 f믄 왜 넣는건가요? format 의미인가요?
print(f'나무를 {n}번째 찍었습니다')
오오~ sinbi 님 안녕하세요? ^-^
추천과 댓글 감사드립니다!!
이 글을 작성할 때 홈짱닷컴을 많이 참조했어요~
홈짱닷컴 짱이에요오! :)

ps.
말씀하신대로 f는 format의 의미에요! ^^

참고로 Python의 문자열 formatting에는 세 가지 방법이 있어요!
1. % formatting: 올드한 스타일
2. String formatting: 조금 진보된 스타일
3. f-string: Python 3.6 이상에서 사용 가능한 모던한 스타일

아래 세 개의 출력문은 모두 "Windows의 최신버전은 11입니다."를 출력합니다 :)

os = 'Windows'
version = 11
print('%s의 최신버전은 %d입니다.' % (os, version))
print('{}의 최신버전은 {}입니다.'.format(os, version))
print(f'{os}의 최신버전은 {version}입니다.')


그럼 sinbi 님께서도 좋은 주말 되세요~ ^^
옙!! 바로 그것이 f-string 방식 문자열 formatting의 장점이죠 ^-^
그럼 휴매니아 님께서도 가족분들과 즐겁고 뜻깊은 주말 되시기를 기원합니다 :)
자세한 설명 감사합니다.
덕분에 저도 공부도 하고 부족한 내용 보충하고 있습니다.

ps.
Python 쓸 일이 없다보니, 기억 저편으로 다 가버렸네요.ㅎ
옙 홈짱닷컴도 더욱 더 번창하시길 기원할게요~!
저야말로 항상 감사드립니다 ^-^
그럼 sinbi 님께서도 맛저 드시고 즐거운 불금 되세요오!
키스 님 안녕하세요? ^-^
추천과 댓글 감사드립니다!
제 코딩 실력이나 글쓰기는 아직 많이 부족합니다 ㅠㅠ
그럼 키스 님께서도 즐거운 주말 되시고 비 조심하세요~! :)
비타주리 님 안녕하세요? ^-^
추천과 댓글 감사드립니다!

제가 실력이 일천하여 감히 '메인페이지'라고 부르기도 민망하지만,
다른 분들과 마찬가지로 LEMP 스택에
Redis를 활용하여 그누보드를 사용하고 있습니다.
서버는 Vultr를 메인으로, Lightsail을 이미지 등 CDN 용도로 사용하고 있습니다.
(비타주리 님께서 사용하시는 닷홈도 테스트 용도로 사용하고 있습니다)

Python은 주로 크롤링 등 보조적인 용도로 활용하고 있고
Flask는 상대적으로 미니멀한 프로젝트에만 사용하고 있습니다 ^^

제가 프론트엔드 방면의 지식이 많이 부족하여 비타주리 님께 늘 많이 배우고 있네요~
그럼 즐겁고 뜻깊은 일요일 되시고, 소나기가 온다는데 비 조심하세요!
항상 감사드립니다 :)
@투엑스비 옙 제 허접한 강의를 읽어주셔서 감사드립니다~! :)
다음 강의도 준비하고 있는데 요새 바빠서 정신이 없네요 ㅠㅠ
그럼 비 조심하시고 편안한 저녁 되세요! ^-^
@comefeel 안녕하세요? ^-^
여러모로 부족한 강의를 읽어주셔서 감사드려요!! :)
그럼 무더위에 항상 건강하시기를 기원합니다~!
@라온헤윰 안녕하세요? ^-^
아직 부족한 점이 많은데 좋게 봐주셔서 감사드립니다!
그럼 오늘도 좋은 오후 되시고, 즐거운 주말 되시기를 기원합니다 :)
감사합니다!!
전체 103
개발강좌 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT