으뜸 파이썬 4장 - 함수와 입출력

DH Park·2024년 6월 27일
post-thumbnail

https://book.naver.com/bookdb/book_detail.nhn?bid=16268369

으뜸 파이썬과 함께 공부하는 포스트입니다.


프로그래밍에서 매우 중요한 역할을 하는 함수에 대해 공부해볼 것이다.

함수란 프로그램 내에서 특정한 작업을 하는 코드의 집합이고, 호출이 될 때 실행된다.

이것은 프로그램을 구성하는 기본적인 구성요소이다.

레고를 예로 들 수 있다. 레고 완성품을 만들려면 잘 조합하고 순서에 맞게 합쳐야 한다. 프로그램도 마찬가지이다.

수만 라인 이상의 큰 프로그램을 만들려면 필요한 기능들을 잘 조합하고 순서에 맞게 나열해야 한다.

함수가 바로 큰 프로그램의 중요한 구성요소 중 하나가 된다.

잘 만들어진 소프트웨어는 이러한 구성요소들의 조직화된 조합이다. 이 구성요소가 프로그램에서 어떤 역할을 하는지 알아보자.

앞에서 언급한 레고 블록과 유사하게 함수는 반복적으로 사용되는 코드를 덩어리(블록)로 묶어 만든다.

이렇게 기능에 따라 미리 만들어진 블록은 필요할 때 호출하여 큰 프로그램을 쉽게 짤 수 있다.

즉 개발자가 직접 만들 수도있고, 다른 파이썬 개발자들이 미리 만들어서 인터프리터와 함께 제공하는 것도 있다. 미리 만들어서 제공하는 함수는 인터프리터에 포함되어 배포되는데, 이를 내장함수라고한다.

조건문을 사용할 때 처음에 if, else 키워드같이 함수 선언에는 def라는 키워드를 사용한다.

def문 다음에는 함수의 이름, 매개변수가 들어갈 괄호, 그리고 함수에서 사용할 매개변수가 순서대로 나타날 수 있다. 매개변수의 다음에는 닫는 괄호와 콜론으로 함수 헤드 작성이 종료된다. 조건문과 같이 들여쓰기를 꼭 해야 한다.

마지막으로 함수는 일을 수행한 후 결과를 return 문으로 반환한다. 반환값이 없으면 return 문은 생략 가능하다.

실행 결과

위 코드는 def키워드로 함수 선언, print_star()라는 함수의 이름을 정해 주었다. 그 다음에 나타나는 괄호 안에는 아무것도 없으므로 매개변수가 없는 함수임을 알수 있다.

콜론 다음 들여쓰기 처리된 함수 몸체에는 별 모양 문자열을 print() 문으로 출력하는 것으로 사용자 정의 함수가 완성되었다.

함수 외부에서 print_star()를 입력하여 호출하면 함수 내부의 print()문이 실행된다.

LAB 4-1 : 함수 정의와 호출

실행 결과

당연한 이야기겠지만, 아무것도 실행되지 않는다.

2. 위 코드를 이용하여 6줄의 별 모양 문자열을 출력하여라.

실행 결과

출력문을 6번 써주면 된다. 아니면 for 문을 이용하여 축약할 수도 있을 것이다.

이번에는 별표를 세개씩 출력하는 함수를 짜보자.

실행 결과

함수 내부에 print문을 세번 쓰는 식으로 함수를 작성할 수 있다.

이 함수를 세번 출력하면 어떻게 될까?

실행 결과

그렇다. 3 * 3 = 9 번이 출력된다. LAB문제에서 했던 것보다는 짧게 할수 있을 것이다.

앞에서 말했듯이 for 문을 같이 사용한다면 더 축약하기 좋을 것이다.

이번에는 별표 한줄, 더하기 기호 한줄 이런 식으로 3번 반복하는 함수를 짜보자.

실행 결과

위 코드에 따르면 사용자 정의 함수를 두개 만들어서 출력할땐 함수 이름을 번갈아 가며 입력하여 출력한다.

지금까지 알아 본 내용을 바탕으로 함수의 장점을 정리 해보자.

  1. 하나의 큰 프로그램을 여러 부분으로 나누어 작성 가능하므로, 구조적인 프로그래밍이 가능하다.

  2. 다른 프로그램에서 함수를 재사용하는 것이 가능하다.

  3. 코드의 가독성이 증가한다.

  4. 프로그램 수정 시에도 일부 함수만 수정하면 되기 때문에 유지 관리가 쉬워진다.

  5. 이미 개발된 함수를 사용하게 되면 프로그램 개발의 시간, 비용을 절약할 수 있다.


이제 함수를 더 편리하게 이용할 수 있는 매개변수에 대해 알아보자.

함수에게 작업을 시킬 때 값을 넘겨주고 일을 시킬 수 있는데, 함수 외부에서 넘겨주는 값을 인자라고한다.

그리고 함수 내에서는 이 인자를 변수 형태로 받아서 사용한다. 이때 함수 내부에서 사용되는 변수를 매개변수라고 한다.

앞에서 몇 번 말한 for문을 함께 사용해 볼 차례이다.

실행 결과

코드를 살펴보면 printstar(4)를 통해 별표가 4번 출력되는 것을 볼 수 있으며, 10번을 출력하려면 print_star(10)과 같이 함수에 전달하는 인자의 값을 변경하면 된다. for 뒤에 사용된 는 for 문에서 range()에 의해 생성된 값 0,1,2,3을 사용하지 않는 경우에 일반적으로 사용한다.

LAB 4-4
print_star(4)를 호출하여 별표 앞에 줄 번호를 0부터 표시하도록 하여라.

실행 결과

보다시피 for 문에 쓰는 변수 대신 입력한 _ 를 print()문에 입력하고, 쉼표로 구분해준 다음, 별표 문을 입력하면 끝나는 간단한 문제이다. 이렇게 줄 번호를 문장과 같이 출력해주면 줄 구분이 쉬워져서 코드를 해석하기 좋다.

위 코드들을 바탕으로 문장을 지정 인자 값만큼 출력하는 프로그램을 작성해보자.

실행 결과

위 코드를 살펴보면 함수 이름 다음 괄호가 나오고, 매개변수 n이 사용된다. 그리고 print()문 내의 'Hello ' * n 명령문을 통해 'Hello ' 가 지정된 횟수 n만큼 반복 수행되었다. 보는 바와 같이 숫자만큼 문장이 반복되게 할 수 있다.

더 나아가 매개변수를 활용하여 수의 합을 구하는 프로그램을 만들어 볼 수 있다.

실행 결과

위 코드의 함수는 a, b라고하는 매개변수를 2개 받아서 두 매개변수를 더해 합을 변수 result에 저장하고 print() 함수로 합을 출력하는 기능이다.

함수 사용시 매개변수의 개수에는 제한이 없다. 다만, 함수 호출시 인자를 하나만 넣으면 다음과 같이 에러가 발생한다. 함수에서 필요한 b라는 매개변수가 없기 때문이다. 주의하도록 하자.

실행 결과


LAB 4-5 두 수 연산을 수행하는 함수

두 매개변수 a,b를 받아 두 수의 곱을 구하여 출력하는 print_mult(a,b) 함수를 구현하여라.

실행 결과

위에서 설명한 두 수의 합을 구하는 함수에서 + 대신 * 인자를 입력해주기만 하면 곱을 구할 수 있다.


앞에서 설명한 코드들에는 return문을 쓰지 않았다. 이제 해보자.

return(반환)문은 값을 되돌려주는 기능이다. 일반적으로 함수 내부는 블랙박스라고 가정한다. 함수 내부는 특정한 코드를 가지고 있으며 주어진 일을 수행하고 결과를 반환할 수 있다.

이와 같이 함수는 어떤 일을 하고 그 결과 값을 호출 문장에 돌려주는 것이 가능하다.

이때 return 키워드를 사용하여 하나 이상의 값을 반환해 줄 수 있다. 실습을 통해 더 알아보자.

실행 결과

매개변수 a, b를 받아 변수 result에 두 매개변수의 합을 저장하고, 그 result값을 return 문으로 반환하였다.

따라서 n1에는 10과 20의 합, n2에는 100과 200의 합이 저장된다. 그러므로 각각 30과 300을 출력한다.

return 을 이용하여 값을 반환할 때는 다음과 같이 return 키워드 다음에 수식을 입력하여 수식의 결과를 반환하는 것도 가능하다.

실행 결과

또한, 함수 외부에 사용하는 두 줄의 코딩도 다음과 같이 한줄로 축약 가능하다.

물론 result 값을 나중에 사용할 일이 없을 때에만 사용하여야 한다.

여기까지 배운 반환문을 가지고 원의 면적과 둘레와 다수의 결과를 반환하는 함수를 만들어보자.

LAB 4-7 원의 면적과 둘레를 구하는 함수

원의 면적과 둘레를 구하기 위해 원의 반지름을 사용하려고 한다. 이 때 사용할 circle_area_circum(radius) 함수는 다음과 같이 반지름(radius) 10을 입력으로 받아서 면적(area)과 둘레(circum)의 두 값을 반환하여라.

실행 결과

LAB 4-8 다수의 결과를 반환하는 함수 만들기

어떤 정수 n과 m을 입력하면 n의 배수 m개를 반환하는 multiplies(n, m) 함수를 구현하고 호출하여 결과를 출력하여라.

실행 결과


전역변수(global variable)

매개변수를 사용하지 않고 외부 변수를 사용하면 어떻게 될까?

실행 결과

이 프로그램은 매개변수를 사용하지 않고 함수 외부에서 a, b를 선언한 후 각각 10, 20 값을 할당하고, 함수 내부에서 두 변수를 더했다.

이 때 함수 내부의 a,b는 외부에서 선언된 변수 a,b를 가져왔는데 이와 같이 함수 바깥에서 선언되거나 전체 영역에서 사용 가능한 변수를 전역변수 라고 한다.

전역변수는 함수의 내부나 외부에서 모두 접근 가능한 변수라는 의미이다. 이 코드는 파이썬 스크립트 파일에서 사용하는 전역변수 a,b를 print_sum() 함수에서 참조하여 사용하는 것과 같은 효과를 볼 수 있다.

이 때문에 print_sum() 함수의 내부와 외부 모두 a, b값이 10,20임을 확인할 수 있다.

이제 a와 b를 print_sum() 함수에서 수정하여 결과를 살펴보자. 함수 내부의 a, b 값을 각각 100, 200으로 수정해보자.

함수 print_sum() 내부에서 a,b는 각각 100, 200이므로 합 result 는 100 + 200 = 300이 된다는 것을 충분히 납득 가능하다. 이제 print_sum() 수행 후 다음 함수 외부에서 다시 한번 a와 b를 합하여 result를 대입하고 그 결과를 출력해보자.

실행 결과

함수 print_sum() 내부에서 a,b는 각각 100, 200이므로 합 result 는 100 + 200 = 300이 된다는 것을 충분히 납득 가능하다.

이제 print_sum() 수행 후 다음 함수 외부에서 다시 한번 a와 b를 합하여 result를 대입하고 그 결과를 출력해보자.

실행 결과

코드를 살펴보면 함수 내부에서 출력한 a, b 변수 값과 외부에서 출력한 a, b의 변수 값이 다르게 출력되는 것을 볼 수 있다.

앞에서 설명했을 때 함수 내부에서 a,b를 사용하면 이 변수가 전역변수 a,b를 가져온다고 했는데 왜 함수 외부에서 사용한 a,b는 10, 20으로 변화가 없을까??

그 이유는 함수 내부에서 a = 100, b = 200과 같이 값을 할당하면 100과 200을 참조하는 정수형 지역변수 a, b가 새로 만들어지기 때문이다.

result = a + b와 같이 a,b에 값을 할당하지 않고 참조하여 사용하게 되면 a,b는 전역변수를 가져와서 사용하기만 한다. 반면 할당을 하게 되면 정수형 객체가 만들어지고, 할당을 한 객체가 지역변수가 된다.

다시 말하자면 a = 100과 같은 할당 연산자는 객체의 생성과 객체를 생성하는 변수를 새롭게 만드는 역할을 한다. 이제 이 코드를 global이라는 키워드를 사용하여 수정해보자.

실행 결과

global a, b와 같은 선언문을 print_sum()함수 내에 사용함으로서 a,와 b는 전역변수가 되어 함수 외부에서 그 값을 확인하여도 100과 200으로 변경되었음을 알 수 있다. global 키워드는 함수 내부에서 반드시 전역변수의 식별자 앞에 사용해야 하며 다음과 같은 할당문에서는 사용할 수 없다.

  • global a = 100 # 문법 오류 발생

이와 같이 명시적으로 전역변수를 사용하면 지역변수를 위한 별도의 메모리를 할당할 필요가 없기 때문에 효율적인 면이 있긴 하지만 전역변수를 많이 사용하면 큰 분량의 코딩시 문제를 일으킬 확률이 굉장히 높아진다. 또한 오류가 나도 어디에서 오류가 났는지 확인하기도 어려워진다. 따라서 전역변수의 사용은 가급적 피하는 것이 좋다.

※ 전역변수의 사용은 파이썬 뿐만 아니라 다른 프로그래밍 언어에서도 좋지 않은 습관이다. 특히 코드가 길어질수록 에러의 원인이 된다. 그러나 전역상수는 나쁘다고 볼 수 없다.

전역상수는 global이라는 키워드로 선언하는데 함수의 외부에서 선언해서 모듈 전체에서 참조할 수 있다. 전역 상수값은 일반적으로 대문자를 사용한다. 아래의 코드를 살펴보면 GLOBAL_VALUE라는 이름의 변수에 1024라는 값을 할당한 후 foo() 함수에서 이 변수 값을 불러서 사용하기 위해 global GLOBAL_VALUE라는 이름으로 선언했다.

예:

profile
Web Deveolper / Offensive Security Consultant (Prev)

0개의 댓글