| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- Chatbot
- 개발일지
- database
- GPT
- psycopg
- 따라하며 배우는 파이썬과 데이터 과학
- 챗봇
- vpc
- AWS
- settings.py
- postgres
- 장고
- 이터널리턴
- Python
- django db with ssh tunnel
- 파이팅
- chartjs-chart-financial
- subnet
- 아나콘다
- ec2
- Django
- vue
- 오픈빌더
- RDS
- pycharm
- SSH Tunnel
- 파이참
- 파이썬
- 파이선
- Today
- Total
우아한 개발계발 블로그
따라하며 배우는 파이썬과 데이터 과학 (6) - 함수로 일처리를 짜임새있게 하자 본문
2021.05.31 - [Study/따라하며 배우는 파이썬과 데이터 과학] - 따라하며 배우는 파이썬과 데이터 과학 (5) - 여러 번 반복하는 일을 하자
따라하며 배우는 파이썬과 데이터 과학 (5) - 여러 번 반복하는 일을 하자
2021.05.30 - [분류 전체보기] - 따라하며 배우는 파이썬과 데이터 과학 (4) - IF! 조건을 따져 실행해 보자 따라하며 배우는 파이썬과 데이터 과학 (4) - IF! 조건을 따져 실행해 보자 2021.05.28 - [Study/따
w00-ah.tistory.com
이제까지는 파이썬의 아주 기본적인 부분만 짚어 보았다. 이제 함수에 대해 알아보고 체계적인 프로그래밍을 해보자
6.1 함수 / 모듈 / 객체
함수를 알기전에 모듈과 객체에 대한 개념도 알아가면 더욱 체계적인 프로그래밍이 가능하다.
함수(Function) : 우리가 반복적으로 사용하는 코드를 묶은 것으로 코드의 덩어리
글만 읽는다면 반복문과 헷갈릴 수 있지만, 반복문에서 코드 블록을 따로 묶어 정의하면 그것이 함수가 된다!
객체(Object) : 코드 중에서 독립적은 단위로 분리할 수 있는 조각
파이썬에서 정의되는 모든 것을 하나의 객체라고 말할 수 있다. 하다못해 변수부터 우리가 앞으로 정의할 함수와, 클래스 등 까지도..
파이썬 용어설명집(Python Glossary)에서는 "객체는 어떠한 속성값과 행동을 가지고 있는 데이터입니다." 라고 말하고 있다. 파이썬의 모든 것들은 각각 다양한 속성과 행동(메소드)가 존재한다. 그렇기 때문에 모든 것이 객체인 것이다.
"Any data with state (attributes or value) and defined behavior (methods)."
모듈(Module) : 프로그램의 일부를 가지고 있는 독립적은 파일.
docs.python.org 에서는 "모듈은 파이썬 정의와 문장들을 담고 있는 파일입니다."라 하고있다.
이전 장에서 언급했다시피 파이썬 코드를 작성하고 저장하면 모듈이라는 형태로 저장된다. 우리는 이런 저장에서 그치는 것이 아니라, 이런 모듈을 불러와 모듈 내의 객체들을 사용할 수 있다.
6.2 def
def 예약어는 함수를 정의하기 위한 예약어 이다. 일단 사용예를 보자
def Funtion():
code1
code2
code3
def 를 쓰고, 함수의 이름을 작성해준다. 그리고 아랫줄엔 들여쓰기를 하여 함수의 코드블록을 정해주고, 명령어들을 작성해준다. 그러면 Function이라는 이름의 함수가 호출될 때 마다, code1, code2, code3 명령어(코드)가 실행되는 것이다.
다른 예를 보자. 네이버의 데이터센터 각의 위치를 출력하는 함수이다.
def Print_location():
print("대한민국")
print("강원도 춘천시 ")
print("동면 순환대로 1231")
Print_location
# <function Print_location at 0x~~~~~~~~~~~~~~~>
Print_location()
# 대한민국
# 강원도 춘천시
# 동면 순환대로 1231
위의 코드를 idle에서 실행시켜보자. (복사 붙여넣기를 하겠다면, 함수 부분을 먼저 복사 붙여넣기하고 아래 명령어를 실행해야한다.)
함수의 이름만 입력하면 우리는 함수를 호출한 것이 아닌 실제 함수가 존재하는 곳에 대한 주소를 출력한다.
그러므로 함수를 호출하려면 함수이름 뒤에 ( ) 괄호를 꼭 써줘야 한다.
6.3 매개변수& 인자
보통 우리가 함수라 하면, 초등학교 부터 고등학교까지 입력-처리-출력의 과정을 수행하는 것으로 알고 있는데, 아직 우리는 함수를 호출을 통한 처리만 수행하고 입력을 수행하지는 않았다.
파이썬의 함수도 '매개변수' 라는 것으로 입력을 받을 수 있다.
매개 변수는 함수 내부에서 쓰이는 독립적인 변수라고 생각하면 편하다.
예시로 간단한 덧셈 함수를 만들어 보자.
def addr(a, b):
print(a+b)
addr(1,2)
# 3
addr 이름의 함수를 정의하고 괄호 안에서 a 와 b를 선언하여 함수에 전달되는 값은 a와 b로 두개 이고,
함수 내부 블록에서는 입력받은 두 값의 합(a+b)을 출력하게 하였다.
함수를 출력하면서 인자로 1과 2를 매개변수 a와b에 전달해 주었고, 함수가 호출되었으므로 a+b의 값인 3이 출력된다.
앞으로 프로그래밍을 공부 하면서 매개변수(Parameter)와 전달인자에(arument)에 대해 헷갈릴 수 있는데, 보통 매개변수는 함수의 정의부분에나열되어 있는 변수를 의미하고, (전달)인자는 함수를 호출할 때 전달되는 실제 값을 의미한다고한다. 자세한 것은 여기를 잠고하자
6.3.1 디폴트 인자
그런데 만약 함수를 호출할 때, 인자를 넣지 않으면 어떻게 될까?
>>> addr()
Traceback (most recent call last):
File "<pyshell#57>", line 1, in <module>
addr()
TypeError: addr() missing 2 required positional arguments: 'a' and 'b'
필요한 값을 넣지 않았으니 당연히 오류가 난다. 이때의 오류를 줄이기 위해 디폴트 인자 (Defalut argument) 라는 개념이 있다.디폴트 인자는 매개변수의 기본값! 이라고 생각하면 편하다
def addr(a=0, b=0):
print(a+b)
addr()
# 0
아무런 오류없이 a와 b의 기본값이 0으로 정해져 있어, 정상적으로 처리되는 모습이다.
6.3.2 키워드 인자
파이썬에서 함수를 호출할 때는 대부분 함수에 선언된 매개변수의 순서대로 인자를 입력한다. # 이를 [위치인자] 라고 한다.
그런데 이런 경우 인자가 많을 때는 코드를 작성하다가 혼동으로 인한 오류를 범할 수 도 있다.
그래서 함수를 호출할 때, 매개변수의 이름, 즉 키워드를 앞에 명시하여 인자들을 구분할 수 있다.
def power(a, b):
print(a**b)
power(2,10)
# 1024
power(10, 2)
# 100
power(a = 2, b = 10)
# 1024
power(b = 10, a = 2)
# 1024
이처럼 a=2,b=10 과 같은 방식으로 어떤 매개변수에 어떤 값이 들어간다라고 명시해주니 오류를 줄일 수 있다.
6.4 RETURN
함수의 입력과 처리에 대해 다루어 보았으니 이제, 출력에 대해 다뤄보자
? 이전 단계에서 덧셈 함수로 수 두의 합을 '출력'했으니 출력에 대해 다루었다고 생각할 수 있으나
이는 인터프리터에 말그대로 출력한 것이지 [함수가] 출력한 것은 아니다.
여기서 출력은 다른 말로 반환 (Return) 이다.
return 예약어는 함수를 종료하면서 return 뒤의 값을 호출된 곳으로 전달하는 예약어이다.
함수가 입력을 받은 값을 처리하여 최종적인 데이터를 반환한다는 것이다. 아까 만든 덧셈기를 가져와서 수정해보자
def addr(a, b):
# print(a+b)
return a+b
addr(1,2)
# 3
이를 인터프리터에서 실행시키면 이전과 같이 3이 출력될 것이다.
무엇이 다른지 확인하고 싶다면 이를 모듈로 저장해서 실행하여보아라. 분명 아 무 것 도 출력되지 않을 것이다.
왜냐하면 함수는 a+b라는 값을 반환했지만, 이를 출력하는 명령어를 입력하지 않았기 때문이다.
그러므로 편집기에서 작성할 때는 아래와 같이 작성해주면, 정상적으로 출력될 것이다.
print(addr(1,2))
# 3
이를 통해 우리는 함수도 하나의 값처럼 다룰 수 있음을 알 수 있다. 함수의 반환 값을 새로운 변수에 저장하고 이를 다시 출력하는 등의 번거로운 일을 하지 않을 수 있다는 것이다.
여기서 추가로 반환 값을 여러개 받을 수 없을까? 상식적으로 입력은 하나인데 반환 값이 복수일 수는 없다.
그러나 복수를 하나로 묶는다면 우리는 하나같은 여러개를 반환할 수 있다.
순서형 자료형이나 매핑형 자료형으로 묶어 반환하면 된다.
list, tuple, set, dictionary 등
예시로 두수를 입력받아 두 수의 합, 차, 곱, 제곱을 반환하는 함수를 만들어보자
def pls_mns_mlt_pwr(a, b):
return a+b,a-b,a*b,a**b
print(pls_mns_mlt_pwr(1,2))
# (3, -1, 2, 1)
여기서는 별도의 묶는 과정없이 (,) 쉼표로 나열하여 반환하였는데, 튜플의 형태로 반환되었음을 확인할 수 있다.
list로 반환하고 싶다면 아래와 같이 return 값들을 [] 대괄호로 감싸주어 형변환하면 된다.
def pls_mns_mlt_pwr(a, b):
return [a+b,a-b,a*b,a**b]
print(pls_mns_mlt_pwr(1,2))
# [3, -1, 2, 1]
이후에 반환 값에 대한 처리는 반환 자료형에 따라 처리하면 된다.
6.5 지역 변수 & 전역 변수
함수로 값을 처리하다가 꼭 입력을 받는 것이 아닌 함수 외부의 값을 처리하고 싶을 수 도 있다.
이때는 global 이라는 예약어를 이용하면된다.
var = "전역"
def func():
var = "지역"
print(var)
func()
print(var)
# 지역
# 전역
맨처음 var에 "전역" 문자열이 들어갔고 후에 func 함수에 이름이 같은 var 이라는 변수에 "지역" 문자열을 할당하였다.
그러나 맨 마지막에 var을 출려할 때는 "전역" 이라는 글자가 출력되었다.
이는 func() 함수 내부의 var은 지역변수이기 "지역" 이 담긴 변수를 새로 초기화하기 때문에 함수 밖에 있는 var과는 다른 변수라는 것이다.
만약 함수 내부에서 함수 외부의 변수에 접근하고 싶을 때, global 을 사용한다.
var = "전역"
def func():
global var # var 을 전역변수로 쓰겠다는 뜻
var = "지역"
print(var)
func()
print(var)
# 지역
# 지역
이처럼 global var 로 var을 전역변수로 선언하여 원래 전역변수에 들어있던 "전역" 문자열이 func 함수에서 "지역"으로 덮어쓰여지게 된다.
전역 변수라고 항상 좋은 것은 아니다. 자칫 스파게티 코드를 만들 수 있고, 프로그램 보안상의 문제도 생길 수 있고,
한번쓰고 말 변수같은 경우는 프로그램 종료까지 메모리를 차지하니 자원 낭비가 아닐 수 없다. 이전부터 계속 강조했던 적제적소의 효율성을 따지며, 전역변수와 지역변수의 사용을 고려해야할 것이다.
첨언하자면, 매개변수도 지역변수다.
6.6 재귀 함수
재귀 함수(recursive function)이란 함수가 자신을 정의할 때, 자기 자신을 재참조하는 방법을 뜻한다. 말은 어려운데
이런건 동영상을 참고하면 이해가 정말 빠르다.
개인적으로 이분의 영상이 초보자가 접하기에 제일 좋다.
예시로 내가 작성한 2의 제곱근에 수렴하는 수열을 재귀함수로 구현한 것을 보자.
def An(n):
if n ==1:
return 1
ret = (An(n-1)+2/An(n-1))/2
return ret
for i in range(1,10):
print(An(i))
# 1
# 1.5
# 1.4166666666666665
# 1.4142156862745097
# 1.4142135623746899
# 1.414213562373095
# 1.414213562373095
# 1.414213562373095
# 1.414213562373095
수열의 초항은 1이므로 n 이 1일 때는 1을 반환하도록하고, 그외의 값들은 수열의 일반식을 따르도록 하였다.
n을 증가할 수록 2의 제곱근에 가까워지는 것을 확인할 수 있다.
인간은 수열을 계산할 때 n에 1부터 넣어서 오름차순으로 계산하겠지만, 이러한 재귀함수로 작성한 코드로된 수열은 내림차순으로 계산하게된다. 만약 함수 An에 10이 들어가게 된다면, An(10)은 An(9)를 호출하고, 이는 다시 An(8)을 호출하고 . . .이를 반복하여 An(2)가 An(1) 이 호출하면 1이 반환되고 An(2)는 (An(1)+2/An(1))/2 의 계산 값을 반환한다. 이를 다시 계속 반복, 반환하여 An(10) 은 (An(9)+2/An(9))/2 의 값을 반환한다.
이렇게 최종적으로 입력값이 클수록 2의 제곱근의 더욱 가까운 근사치를 반환하는 재귀함수가 만ㄷㄹ어졌다.
재귀함수에 대해서는 할말이 너무나도 많다. 재귀함수의 호출 / 실행 구조라던가, 메모리에 미치는 영향이라던가 할말은 굉장히 많지만 초보자의 입장에서는 재귀함수를 이해하는 것만으로도 충분하다.
6.7 모듈의 사용
우리는 이미 import 라는 예약어를 접해봤다.
우리가 아까만든 덧셈 함수, 뺄셈 함수 그외 여러 함수들을 저장한 모듈 (=스크립트 파일)을 import를 통해 불러와서 사용할 수 있다.
만약 모듈이름을 calc.py 라고 저장했다면, 같은 경로 내에서 다음과 같이 불러와 사용할 수 있다.
import calc
print(calc.addr(1,2))
# 3
from calc import addr
print(addr(1,2))
# 3
from calc import addr as ad
print(ad(1,2))
# 3
세 개의 import 방식은 크게 다를 것이 없지만 첫번째는 모듈 전체를 불러와서 모듈 내의 함수, 클래스, 메소드 등을 사용하는 것이고, 두번째, 세번째는 calc 모듈에서 addr 함수만 불러와 사용하는 것이다.
두번째와 세번째의 차이는 별명의 차이다. as 예약어는 앞에오는 명령어를 뒤에오는 별칭으로 사용하겠다는 것이다.
위의 코드에서는 addr 를 ad 라는 이름으로 사용하겠다는 것이다.
'Study > 따라하며 배우는 파이썬과 데이터 과학' 카테고리의 다른 글
| 따라하며 배우는 파이썬과 데이터 과학 (8) - 연관된 데이터를 딕셔너리로 짝을 짓자 (0) | 2021.06.20 |
|---|---|
| 따라하며 배우는 파이썬과 데이터 과학 (7) - 데이터를 리스트와 튜플로 묶어보자 (0) | 2021.06.20 |
| 따라하며 배우는 파이썬과 데이터 과학 (5) - 여러 번 반복하는 일을 하자 (0) | 2021.05.31 |
| 따라하며 배우는 파이썬과 데이터 과학 (4) - IF! 조건을 따져 실행해 보자 (0) | 2021.05.30 |
| 따라하며 배우는 파이썬과 데이터 과학 (3) - 연산자로 연산을 해 보자 (0) | 2021.05.28 |