파이썬의 변수와 함수에 대해 알아보기
파이썬의 변수
파이썬의 변수에 대해서 알아보도록 하자.
변수에 대한 간단 설명
변수란, ‘변할수 있는것’으로 어떠한 값을 담을 수 있는 ‘상자’ 라고 생각하면 쉽다.
변수를 만드는 방법
a = 10
예를들어 a = 10 이라고 한다면 10을 a라는 상자에 담는다는 뜻이다.
(그리고 이것을 ‘변수를 선언한다’라고 표현)
즉 변수_이름 = 변수에_저장할_값 으로 지정이 가능하다.
print(a)
우리가 변수에 넣은 값이 잘 들어갔는지 확인하려면, print()함수 를 활용하여 출력하면 된다.
1. 여러개의 변수를 한번에 선언 하고 싶으면?
a= 10
a,b = (10,20)
[a,b] = [10,20]
a = b = 10
a = None
- a= 10
- a,b = (10,20) : 튜플을 이용하여 각각 값을 할당
- [a,b] = [10,20] : 리스트를 이용하여 각각 값을 할당
- a = b = 10 : a와 b 모두에 똑같은 값을 할당
- a = None : 비어있는 변수값을 만들때 사용
2. 변수의 이름을 선언할때 규칙!
변수를 선언할때 지켜야 할 규칙이 존재한다.
- 영문자 혹은 _ 로 시작해야 한다.
- 숫자로 시작할 수 없다.
- 특수문자(+, -, %, 등 여러기호)는 사용할 수 없다.
- 변수 이름에 공백이 있으면 안 된다.( 보통 _로 이어주거나 대소문자로 구분)
- 파이썬의 함수 및 예약어 등은 사용할 수 없다.
변수 교환(swap)에 대한 설명
각각의 변수를 선언하고 두 변수에 들어있는 값을 서로 바꿔주는 방법에 대해 설명하겠다.
a = 10
b = 100
위와 같은 변수가 있다.
그전에 기본적으로 변수에 대해 알아야 할 것이 있는데, 우리가 변수를 선언하면
램에 있는 메모리 공간에 데이터를 저장할 수 있는 공간이 각각 할당된다.
a=10 을 위에서는 쉽게 설명하기 위해 10을 a에 담는다고 표현 했지만, 더 자세히 설명하면
‘10이 있는 주소’를 ‘a’라는 상자(변수)에 넣는 것이다.
위의 설명과 마찬가지로 b=100 또한 100이 있는 주소를 b라는 상자(변수)에 넣는다고 생각하면 쉽다.
- 더 쉽게 설명하자면 box=”돈” 이라고 선언했을 경우 그 box에 직접 들어가는 것이 아닌
돈이 있는 주소가 적힌 종이를 상자에 넣는다고 생각하면 쉽다.
변수 교환을 하는 방법
이제 변수교환을 직접 해보도록 하자.
파이썬의 경우 다른 프로그래밍 언어와 다르게 훨씬 간단한 방법으로 교환이 가능하다.
(다른 프로그래밍 언어에서는 또 다른 빈 변수(상자)를 만들어 변수에 값을 교환해야한다.)
a = 10
b = 2000
먼저 위와 같이 변수 a와b를 각각 10, 2000 으로 선언한다.
a = 10
b = 2000
a , b = b, a
a , b 로 a 와 b 에 있는 값을 서로 변경해주면 끝이다.
변수에 대한 심화 내용
변수에 대한 기본적인 내용을 위에서 알아봤으니 조금 더 심화 내용을 다뤄보도록 하겠다.
리스트의 값 변경하기
a = [10,20,30]
위와 같이 변수 a 에 [10,20,30]이라는 리스트 값을 넣어준다.
a 는 그 리스트가 있는 주소를 담게 되며, 리스트의 각각의 방에 10,20,30의 값이 들어간다.
- 리스트에 대한 설명 보러가기 :
a = [10,20,30]
b = a
다음으로 위와 같이 b = a 로 변수 b 에 a 리스트의 주소를 넣어줬다.
(a와 b의 주소는 같다.)
a = [10,20,30]
b = a
a[0] = 200
a[0] = 200 이라는 것은 a 에 0번째(인덱스)에 있는 값을 200으로 바꾼다는 의미다.
(여기서는 쉽게 0이라는 이름의 방에 있는 값을 200으로 바꿔줬다고 생각하면 된다.)
a = [10,20,30]
b = a
a[0] = 200
print(b)
그리고 print(b) 로 실행하게 되면, b 에 들어가 있는 값이 [200, 20 , 30]으로 나오게 된다.
즉 리스트의 첫번째 값이 10 -> 200으로 바뀐것이다.
그런데 왜 a의 값을 변경하였는데 b의 값이 같이 바뀌었는지 궁금하지 않은가?
여기서 바로 아까 설명했던 ‘주소’를 저장한다는 개념을 이해하는 것이 필요한다.
b = a 에서 a 의 값이 복사되어 b 로 들어간 것이 아닌 a 의 ‘주소’를 가지게 되는것 이다.
즉 a 와 b 가 같은 곳에 있기 때문에 a 의 값을 변경하면 b 의 값이 같이 바뀌게 되는것.
a 의 값만 변경되고 b 의 값은 변경되지 않게하는 방법은?
a 의 복사본을 b에게 주고 a의 값이 변화할 때 b는 변하지 않게 하려면
슬라이싱[:] 을 이용하면 된다.
- 1.변수 a에 [1,2,3]으로 하나의 리스트를 만들어 넣어준다.
a = [1,2,3]
- 2.두번째로 b=a[:]를 이용하여 a의 값들을 각각 슬라이싱 하여 b에 복사해서 넣어준다.
a = [1,2,3]
b = a[:]
- 3.마지막으로 a[0]=4 (a라는 리스트의 0번째 방의 값을 4로 바꿈)하게되면 b는 바뀌지않고 a만 바뀌는것을 확인할 수 있다.
a = [1,2,3]
b = a[:]
a[0] = 4
파이썬의 함수
파이썬에는 함수라는것이 존재한다. 함수에 대해서 알아보자.
파이썬의 함수에 대한 설명
함수란, 어떠한 입력값을 가지고 어떤 일을 수행한 후 그 결과물을 내어 놓는 것이다.
조금 더 쉽게 설명하자면 믹서기를 떠올려보자.
이때 우리가 믹서에 넣는 과일은 ‘입력’, 그 결과물인 과일주스가 ‘출력(결과값)’이 되는 것이다.
즉 어떠한 입력값을 가지고 어떤 일을 수행하여 그 결과물을 내어 놓는 것이 바로 함수가 하는 일이라고 생각하면 된다.
함수는 매우 중요하므로 좀 더 자세히 알아보도록 하겠다.
파이썬의 함수를 사용하는 이유가 뭘까?
프로그래밍을 하다 보면 같은 내용을 여러번 반복하여 작성하는 경우가 존재한다. 이때 바로 함수가 필요하다.
반복되는 부분이 있을 경우, ‘반복적으로 사용되는 부분’을 한번에 묶어 ‘지정한 입력값을 주었을때 어떤 결과값을 반환해 준다’ 라는 식의 함수로 작성하면 된다.
함수를 사용하는 또 다른 이유는 작성한 프로그램을 기능 단위의 함수로 분리해 놓게되면 프로그램 흐름을 더 쉽게 파악할 수 있기 때문이다.
마치 음식이 여러가지 재료가 섞여 요리하는 과정을 거쳐 하나의 음식이 되는 것처럼 프로그램에서도 입력한 값이 여러 함수를 거치며 원하는 결과값을 낸다.
(그렇게해야 프로그램 흐름을 잘 파악하여 오류가 어디에서 발생하는지 알기 쉽다.)
파이썬 함수의 구조
def 함수_이름(매개변수):
수행할_문장1
수행할_문장2
...
파이썬 함수의 구조는 위와 같다.
def 는 함수를 만들 때 사용하는 예약어(키워드)이다.
(파이썬은 함수가 값을 리턴하는지, 어떤 타입의 값을 리턴하는지를 함수 정의부분에 적지 않는다.)
함수 이름은 임의로 설정하여 만들 수 있다.
(이때 함수 이름은 내가 사용하고자 하는 의도에 맞게 잘 지어줘야 알기 편하다.)
함수 이름 뒤 괄호안의 매개변수는 이 함수에 입력으로 전달되는 값을 받는 변수이다.
(정의한 함수를 호출한 쪽에서 넘겨준 값을 받아 사용할수 있는 변수를 의미)
함수를 정의한 후, 반복문 이나 조건문 if, while, for 문 등과 마찬가지로 함수에서 수행할 문장을 입력해주면 된다.
def add(a, b):
return a + b
위 함수는 다음과 같이 해석된다.
- 이 함수의 이름은 add 이며 입력으로 2개의 a,b의 값을 받으며 리턴값(출력값)은 2개의 입력값을 더한 값이다.
def add(a, b):
return a+ b
여기에서 return은 함수의 결과값(리턴값)을 리턴하는 명령어이다.
- retrun에 대한 간단설명 :
함수를 실행 시키면 어떤 값을 돌려받는다라는 의미이다.
리턴 값은 함수가 호출될 때 생성된 출력이나 결과이며, 리턴값은 숫자,문자,리스트, 튜플 등 모든 데이터 유형이 될 수 있다.
(만일 리턴문이 지정되지 않은 경우에는 None을 반환하게 된다.)
이제 직접 만든 함수를 사용해 보도록 하자.
a = 10
b = 5
c = add(a, b) # add(10, 5)의 return 값을 c에 대입
print(c)
#결과 = 10 + 5 하여 15가 나오게 된다.
변수 a에 10을 변수 b에 5를 대입해준 뒤 앞에서 만든 add 함수에 a와 b를 입력값으로 넣어준다.
그리고 변수 c에 add 함수에 대한 리턴값을 대입하여 print(c)로 결과값인 c의 값을 확인할 수 있다.
매개변수와 인수에 대한 설명
매개변수(parameter)와 인수(arguments)는 혼용해서 사용하는 용어이다.
매개변수는 함수에 입력으로 전달된 값을 받는 변수이다.
인수는 함수를 호출할 때 전달하는 입력값을 의미한다.
def add(a, b): # a, b는 매개변수
return a+b
print(add(3, 4)) # 3, 4는 인수
위의 코드를 보면 이해하기 더 쉬울거라고 생각합니다.
같은 의미를 가진 여러가지 용어에 주의
프로그래밍을 공부하다 보면 어려운 부분 중 하나가 용어의 혼용이다.
우리는 살아가면서 의미는 같지만 표현이 다른 용어를 종종 만나게 된다.
한 예로 입력값을 다른 표현으로는 함수의 인수, 파라미터, 매개변수 등으로 말하기도 하며,
함수의 리턴값을 결과값, 출력값, 반환값, 돌려주는 값 등으로 말하기도 한다.
이렇듯 많은 용어가 다른 여러가지의 말로 표현되지만 결국 의미는 동일한 경우가 많다.
따라서 이런 용어를 기억해야 헷갈리지 않을 수 있다.
입력값과 리턴값에 따른 함수의 형태에 대해 알아보기
함수의 형태는 입력값과 리턴값의 존재 유무에 따라 4가지 유형으로 나뉜다.
일반적인 함수, 입력값이 없는 함수, 리턴값이 업는 함수, 입력값과 리턴값이 둘다 없는 함수
먼저 일반적인 함수에 대해 알아보도록 하자.
1. 일반적인 함수
입력값이 있고 리턴값이 있는 함수가 일반적인 함수라고 볼수 있다.
def 함수_이름(매개변수):
수행할_문장\
...
return 리턴해줄 값
앞으로 프로그래밍을 할 때 만들 함수는 대부분 위와 비슷한 형태를 가지고 있을것이다.
def add(a, b):
result = a + b
return result
위의 보이는 것이 일반적인 함수의 전형적인 예이다. 풀이를 해보자면 add 함수는 2개의 a,b 의 입력값을 받아 서로 더한 결과값을 리턴한다는 의미이다.
이 함수를 사용하는 방법은 밑에 코드처럼 사용하면 된다.
a = add(3,4)
print(a)
# 결과값으로 7이 리턴된다.
이때 의문점을 가지는 사람이 있을수도 있다.
a와 b의 값을 따로 지정해주지 않았는데 왜 7이라는 결과가 나온걸까?
여기서 만든 add 함수는 a와 b 두 개의 매개변수를 받아온다. 그리고 함수를 호출할 때 3과 4라는 두개의 값을 전달했기 때문에
이 두 값이 함수 내부에서 a와 b에 각각 할당되어 계산에 사용되었으며, 그 결과가 반환되어 a에 저장되서 7이라는 결과가 나오게 된것이다.
아까 위에서는 a에 10 b에 5를 지정해주었지만 이렇게 a와 b를 따로 지정해 주지않아도 전달한 두개의 값(3,4)이 a와 b로 들어가게 된것이다.
이처럼 입력값과 리턴값이 있는 함수의 사용법을 정리하자면 다음과 같다.
리턴값을_받을_변수 = 함수_이름(입력_인수1, 입력_인수2, …)
2. 입력값이 없는 함수
입력값이 없는 함수가 존재할까?
입력값이 없는 함수에 대해서 알아보도록 하자.
def say():
return "Hi"
위처럼 say() 라는 이름의 함수를 만들었다. 그런데 매개변수 부분을 나타내는 함수의 이름 뒤의 괄호 안이 비어져 있다.
그렇다면 이 함수는 어떻게 사용해야 할까?
a = say()
print(a)
#결과값 Hi
위처럼 코드를 작성해주게되면 결과값으로 Hi 라는 문자열이 출력된것을 볼수 있다.
위 함수를 쓰기 위해서는 say()처럼 괄호 안에 아무런 값도 넣지 않고 비어줘야 한다.
이 함수는 입력값은 없지만, 리턴값으로 “Hi” 라는 문자열을 받아 리턴한다.
즉 a = say() 처럼 작성하게 될경우 a 에 “Hi” 라는 문자열이 대입되게 되는 것이다.
- 작동원리를 조금 더 자세히 설명해보도록 하겠다.
- def say() : say() 라는 이름의 함수를 정의해준다. 소괄호 안은 매개변수를 의미하는데 비어두면 없는것을 의미.
- retrun “Hi” : 함수가 호출될 때 “Hi” 라는 문자열을 반환하는 부분.
- a = say() : 이 부분은 say 함수를 호출하여 반환된 값을 변수 a에 저장하는것. 여기서 say함수가 호출되고 -> “Hi”라는 값이 반환되어 a에 저장.
- print(a) : 마지막으로 a에 저장된 값을 출력하는 부분으로 a에 저장된 “Hi”가 출력되게 되는것.
이처럼 입력값이 없고 리턴값만 존재하는 함수는 다음과 같이 사용한다.
리턴값을_받을_변수 = 함수_이름()
3. 리턴값이 없는 함수
리턴값이 없는 함수도 존재한다.
def add(a, b):
print("%d, %d의 합은 %d입니다." % (a, b, a+b))
- %d에 대한 간단 설명!
위에서 %d는 문자열 포맷팅에서 정수를 대체할 위치를 나타내는 것이다.
문자열 내부에서 %d를 사용하고 그 뒤에 % 연산자와 함께 정수를 지정해주게 되면 해당 위치에 정수가 대체된다.
위의 코드를 보면 리턴값이 없다.
리턴값이 없는 함수는 호출해도 리턴값이 없기 때문에 사용하는 방법이 따로 존재한다.
add(10 ,5)
# 출력값 10,5의 합은 15입니다.
위의 코드처럼 작성하게되면 터미널에 출력값으로 나오게 된다.
이처럼 리턴값이 없는 함수는 다음과 같이 사용한다.
함수_이름(입력_인수1, 입력_인수2, …)
자 그런데 여기서 ‘10, 5의 합은 15입니다’ 라는 문장이 출력되었는데 왜 리턴값이 없다고 하는지 의문이 들것이다.
print()문은 함수의 구성 요소 중 하나로써 ‘수행할_문장’에 해당하는 부분일 뿐이기 때문에
리턴값은 당연히 없는것이다. 리턴값은 오직 return 명령어로만 돌려 받을 수 있다.
a = add(10, 5)
# 결과값 10,5의 합은 15입니다.
print(a)
# 결과값 None
위를 보게되면 알수 있는것이 a의 값이 None으로 출력 되었다는 것이다.
None이란 ‘거짓을 나타내는 자료형’으로 “아무것도 없음” 혹은 “값이 없음” 을 나타낸다. 즉 아무런 값이 없다는 의미.
위의 add() 함수처럼 리턴값이 없을 때 a=add(10, 5) 라고 쓰면 함수 add()는 리턴값으로 a 변수에 None 을 리턴하게 된다.
즉 None을 리턴한다는것은 리턴값이 없다는 의미.(return 값을 지정해주지 않으면 자동으로 None으로 지정된다.)
4. 입력값도 리턴값도 없는 함수
입력값도 리턴값도 없는 함수도 역시 존재한다. 이를 알아보도록 하자.
def say():
print("Hi")
입력 인수를 받는 매개변수도 없고 return 문 또한 없으니 입력값과 리턴값이 둘다 없는 함수이다.
이 함수를 사용할 수 있는 방법은 단 1가지다.
say()
# 결과갑 Hi
즉 입력값도, 리턴값도 없는 함수는 이렇게만 사용할 수 있다.
함수_이름()
매개변수를 지정하여 호출하는 방법
함수를 호출할 때 매개변수를 지정해줄수 있다.
def sub(a, b):
return a - b
위처럼 2개의 숫자를 입력받은 후 첫번째 수에서 두번째 수를 뺼셈하여 리턴하는 sub 함수를 만들었다.
이 함수는 밑에 코드와 같이 매개변수를 지정해줄수 있다.
result = sub(a=7 , b=3) # a에 7 , b에 3을 전달
print(result)
#결과값 4
위의 코드처럼 a에 7을 전달하고 b에 3을 전달하여 a - b 즉 7 - 3 이 되어 결과값으로 4라는 값이 출력된다.
또한 매개변수를 지정해주면 밑에 코드와 같이 순서에 상관없이 사용할수도 있다.
result = sub(b=5, a=3) # b에 5, a에 3을 전달
print(result)
#결과값 -2
위의 코드처럼 a에 3을 전달하고 b에 5를 전달하여 3 - 5 가 되어 결과값으로 -2 라는 값이 출력된다.
입력값이 몇개가 될지 모른다면 어떻게 해야 할까?
입력값이 여러개 존재할때 그 입력값을 모두 더해 주는 함수를 생각해보도록 하자.
하지만 몇개가 입력될지 모르는 경우에 어떻게 해야 할까?
파이썬은 이러한 문제를 해결하기 위해서 다음과 같은 방법을 제공한다.
def 함수_이름(*매개변수):
수행할_문장
...
일반적으로 볼수 있는 함수 형태에서 괄호 안의 매개변수 부분이 *매개변수로 바뀌었다.
여러개의 입력값을 받는 함수 만들기
여러 개의 입력값을 모두 더하는 함수를 직접 만들어보도록 하자.
예를 들어보겠다.
add_many(1, 2) 인 경우 3,
add_many(1,2,3) 인 경우 6,
add_many(1,2,3,4,5,6,7,8,9,10) 인 경우 55를 리턴하는 함수를 만들어 보겠다.
def add_many(*args):
result = 0
for i in args:
result = result + i # *args에 입력받은 모든 값을 더한다.
retrun rersult
위에서 만든 add_many 함수는 입력값이 몇개여도 상관이 없다.
*args처럼 매개변수 이름앞에 *을 붙이면 입력값을 전부 모아 튜플로 만들어 주기 때문이다.
만약 add_many(1,2,3)처럼 이 함수를 쓰면 args는 (1,2,3)이 되는 것이고,
add_many(1,2,3,4,5,6,7,8,9,10) 처럼 쓰면 args는 (1,2,3,4,5,6,7,8,9,10)이 되는 것이다.
이때 여기에서 *args는 임의로 정하 변수 이름이어서 원하는 아무 이름이나 사용해도 된다.( ex *test)
(args는 인수를 뜻하는 영어 단어 arguments의 약자이다. 관례적으로 자주 사용된다.)
-
for i in args 이부분은 반복문이다.
여기서 args 는 반복할 수 있는 객체를 나타내며, 이 객체의 각 요소를 순차적으로 변수 i에 할당하면서 루프(반복)를 실행한다.
(리스트나 튜플과 같은 시퀸스 형태의 객체, 또는 문자열 같은 반복 가능한 객체를 사용할 수 있다.)
즉 args를 i에 넣는다는 의미이며 그 i값을 result = 0 인 0의 값에 + 해준다는 의미이다. -
좀 더 쉽고 자세한 설명
- args(임의로 설정한것)의 첫번째 요소를 i 에 할당
- 루프 본문을 실행한다. 이때 i는 args의 첫 번째 요소를 가리킴
- 루프 본문 실행이 끝나면 args의 두 번째 요소를 i에 할당한뒤 다시 루프 본문을 실행
- args의 모든 요소에 대해 위의 과정을 반복한다.
자 이제 위에서 작성한 add_many()함수를 사용해보도록 하자.
result = add_many(1,2,3)
print(result)
#결과값 6
- 위의 결과값 6이 어떤식으로 반복되어 나왔는지 더 쉽게 설명
- 순차적으로 args의 1이 i에 할당되서 result에 더해지며 result는 즉 0 + 1 = 1
- 다음으로 i에 2가 할당되어 result에 더해지기 때문에 result는 아까 저장된 1이 있기 때문에 1 + 2 = 3
- 마지막으로 i에 3이 할당되고 result에 더해지는데 아까 저장된 result는 3이기 떄문에 3 + 3 = 6
- 이런 과정을 통해 최종적으로 6이라는 결과값이 나오게 된다.
result = add_many(1,2,3,4,5,6,7,8,9,10)
print(result)
#결과값 55
즉 위의 코드도 마찬가지로 1부터 10까지 반복되어 55라는 결과값이 나오는것을 알수있다.
매개변수는 여러개 사용할수 있다.
여러개의 입력을 처리할 때 def add_many(*args)처럼 함수의 매개변수로 하나만 사용할 수 있는것은 아니다.
def add_mul(choice, *args):
if choice == "add":
result = 0
for i in args:
result = result + i
elif choice == "mul":
result = 1
for i in args:
result = result * i
return result
(인터프리터에 작성하기에 소스 코드가 너무 많다면 에디터를 사용하는것도 좋다.)
add_mul() 함수는 여러개의 입력값을 의미하는 *args 매개변수의 앞에 choice 매개변수가 추가된것을 볼수 있다.
이 함수는 밑의 코드와 같이 사용할수 있다.
result = add_mul('add', 1,2,3,4,5)
print(result)
#결과값 15
result = add_mul('mul', 1,2,3,4,5)
print(result)
#결과값 120
매개변수 choice에 ‘add’가 입력된 경우에는 *args에 입력되는 모든 값을 더해 15를 리턴하고
‘mul’이 입력된 경우에는 *args에 입력되는 모든 값을 곱해 120을 리턴해준다.
(이때 ‘add’나 ‘mul’은 원하는 이름으로 지정해서 사용가능하다.)
즉 이런식으로 여러개의 매개변수도 사용이 가능하다.
키워드 매개변수에 대해 알아보기
이번에는 키워드 매개변수 kwargs 에 대해서 알아보도록 하겠다.
키워드 매개변수를 사용할 때는 매개변수 앞에 별2개(**)를 붙여준다.
먼저 아래와 같은 함수를 작성하겠다.
def print_kwargs(**kwargs):
print(kwargs)
위의 print_kwargs() 함수는 입력받은 매개변수 kwargs를 출력하는 단순한 함수다.
print_kwargs(a=1)
#결과값 {'a' : 1}
print_kwargs(name="foo", age = 3)
#결과값 {'age' : 3, 'name' : 'foo'}
함수의 입력값으로 a=1이 사용되면 kwargs는 {‘a’:1}이라는 딕셔너리가 되고
입력값으로 name=’foo’, age=3 이 사용되면 kwargs는 {‘age’:3 , ‘name’:foo}라는 딕셔너리가 된다.
**kwargs처럼 매개변수 이름 앞에 **을 붙여주게되면 매개변수 kwargs는 딕셔너리가 되고
모든 key=value 형태의 입력값이 딕셔너리에 저장된다.
(kwargs는 ‘keyword arguments’ 의 약자이다.)
- 딕셔너리에 대한 간단 설명 : 버튼이 만들어질 예정입니다.
딕셔너리는 key와 value를 한 쌍으로 가지는 자료형이다.
예를 들어 key가 ‘baseball’ 이라면 value는 ‘야구’ 가 되는 것이다.
사용하는 방법은 {}를 사용하여 만들며 :(콜론)으로 구분지어 key와 value를 구분한다.
즉 위에서 name이라는 key에 ‘foo’라는 value가 들어간것이고 age라는 key에 3이라는 value가 들어간것이다.
함수의 리턴값은 언제나 하나입니다
def add_and_mul(a,b):
return a+b, a*b
위의 코드에서 add_and_mul() 함수는 2개의 입력 인수를 받아 더한 값과 곱한 값을 리턴하는 함수를 뜻한다.
이 함수를 아래와 같이 호출해보도록 하겠다.
result = add_and_mul(3,4)
리턴값은 a+b와 ab인데, 리턴값을 받아들이는 변수는 result 하나만 쓰였기때문에 오류가 발생할까?
그러나 이때 오류는 발생하지 않는다. 그 이유는 함수의 리턴값은 2개가 아니라 언제나 1개 이기 때문이다.
add_and_mul 함수의 리턴값 a+b와 ab는 튜플값 하나인 (a+b, a*b)로 리턴된다.
- 튜플에 대한 간단 설명 : 버튼이 만들어질 예정입니다.
튜플은 여러개의 값을 가질 수 있는(셀수 있는 수량의 순서가 있는것) 순차적 자료를 의미한다.
튜플은 ()를 사용하여 만들며, 값이 1개만 들어있는 튜플을 만드는 경우에 Tuple = (1, ) 처럼 만들어야한다.
튜플은 값을 한 번 설정하면 변경할 수 없다.(튜플은 상수와 같은 성질을 가지고 있다.)
(상수란 값을 한번 설정하면 변경할 수 없는 값을 의미)
튜플의 구조는 여러개의 요소를 가지는데, 각 요소는 순서가 있고, 인덱스(index)를 가진다.
이때 튜플의 첫 번째 요소의 인덱스는 0부터 시작한다.(1로 시작하는것이 아니기때문에 주의!)
그래서 result 변수는 다음과 같은 값을 가지게 된다.
result = (7, 12)
결과값으로 (7, 12)라는 튜플 값을 가지게 되는 것이다.
만약 이 하나의 튜플 값을 2개의 값으로 분리하려면 어떻게 해야할까?
result1, result2 = add_and_mul(3 ,4)
위의 코드와 같이 호출해주면 된다.
이렇게 호출하게 되면 result1, result2 = ( 7, 12 ) 가 됨으로써 result1 = 7 , reslut2 = 12가 된다.
자 그렇다면 return문을 2번 사용하면 2개의 리턴값을 돌려주지 않을까? 하는 의문이 생길수도 있다.
def add_and_mul(a,b):
return a+b
return a*b
#결과값 a+b만 출력된다.
이렇게 할 경우 원하는 결과가 나오지 않고 a+b의 값만 나오게 된다.
result = add_and_mul(2,3)
print(result)
#결과값 5
위의 코드의 결과값처럼 add_and_mul(2,3)의 return값은 5 하나뿐이다. 두번째 retrun a*b는 실행되지 않았기때문인데
이유는 파이썬에서 함수는 한번에 하나의 return문만 실행하고 남은 return 문은 실행하지 않기 때문이다.
결론적으로 함수는 return 문을 만나는 순간, 리턴값을 돌려 준 다음 함수를 빠져나가게 된다.
따라서 이 함수는 밑의 코드와 완전히 동일한다.
def add_and_mul(a,b):
retunr a+b
다시 한번 설명하지만 함수는 return문을 만난는 순간 결과값을 돌려준다음 함수를 빠져나간다.
만약 두개의 값을 얻고 싶다면?
def add_and_mul(a,b):
return a+b, a*b
아까 위에서 작성한 코드와 같이 이렇게 작성해주면 된다.
이렇게 할 경우 함수가 두개의 값을 튜플로 반환해주게 된다.
return의 또 다른 쓰임새
특별한 상황인 경우에 함수를 빠져나가고 싶으면 retrun을 단독으로 써서 함수를 즉시 빠져나갈 수 있다.
def say_like(acc):
if like == "금":
return
print("내가 좋아하는것은 %s 입니다." % like)
위는 매개변수 like로 좋아하는것을 입력받아 출력하는 함수인데, 이 함수 역시 리턴값이 없다.
(이때 문자열을 출력한다는 것과 리턴값이 있다는 것은 전혀 다른 말이므로 꼭 주의하자 !)
함수의 리턴값은 오로지 return 문에 의해서만 생성된다.
say_like("은")
#결과값 내가 좋아하는것은 은입니다.
say_like("금")
#결과값없음
만약 위처럼 입력값으로 “금” 이라는 값이 들어오면 문자열을 출력하지 않고 함수를 즉시 빠져나가게 된다.
이처럼 리턴값이 없는 함수에서 retrun으로 함수를 빠져나가는 방법은 실제 프로그래밍에서 자주 사용한다.
매개변수 초기값을 미리 설정하는 방법
이번에는 조금 다른 형태로 함수의 인수를 전달하는 방법에 대해 알아보도록 하자.
다음은 매개변수에 초기값을 미리 설정해주는 경우다.
# default1.py
def say_myself(name, age, man=True):
print("나의 이름은 %s 입니다." % name)
print("나이는 %d살입니다." % age)
if man:
print("남자입니다.")
else:
print("여자입니다.")
위 코드의 함수를 보면 매개변수가 name, age, man=True 이다.
그런데 낯선 것이 하나 있는데, man=True 처럼 매개변수에 미리 값을 넣어 준 것이다.
이것이 바로 함수의 매개변수에 초기값을 설정하는 방법이다.
say_myself 함수는 다음처럼 2가지 방법으로 사용된다.
say_myself("박응용", 27)
say_myself("박응용", 27, True)
입력값으로 (“박응용”, 27) 처럼 2개를 주게되면 name엔느 “박응용”, age에는 27이 대입.
그리고 man 이라는 변수에는 입력값을 주지 않았지만, man은 초기값 True를 갖게된다.
따라서 위 예에서 say_myself 함수를 사용한 2가지 방법은 모두 다음처럼 동일한 결과를 출력하게된다.
나의 이름은 박응용입니다.
나이는 27살입니다.
남자입니다.
이제 초기값이 설정된 부분은 Flase로 바꿔 호출해보도록 하자.
say_myself("박응선", 27, False)
man 변수에 False 값이 대입되어 밑의 결과가 출력되게 된다.
나의 이름은 박응선입니다.
나이는 27살입니다.
여자입니다.
함수의 매개변수에 초깃값을 설정할 때 주의해야 할것이 있다.
만약 위에서 살펴본 say_myself 함수를 밑의 코드와 같이 만들면 어떻게 될까?
# default2.py
def say_myself(name, man=True, age):
print("나의 이름은 %s 입니다." % name)
print("나이는 %d살입니다." % age)
if man:
print("남자입니다.")
else:
print("여자입니다.")
이전 함수와 바뀐 부분은 초기값을 설정한 매개변수 위치이다.
결론을 미리 말하자면 이것은 함수를 실행할 때 오류가 발생하게된다.
say_myself("박응용", 27)
위의 코드와 같이 함수를 호출하면 된다고 생각하겠지만 아니다.
이유는 위와 같이 함수를 호출하게되면 name 변수에는 “박응용”이 들어갈 것이다.
하지만 파이썬 인터프리터는 27을 man 매개변수와 age 매개변수중 어느곳에
대입해야 할지 판단하기 어려우므로 이러한 상황에서는 오류가 발생하게 된다.
SyntaxError: non-default argument follows default argument
위의 오류 메세지는 ‘초깃값이 없는 매개변수(age)는 초깃값이 있는 매개변수(man) 뒤에 사용할 수 없다’라는 뜻이다.
다시말해 매개변수로(name, age, man=True)는 가능하지만, (name, man=True, age)는 안된다.
초기화하고 싶은 매개변수는 항상 뒤쪽에 놓아야 한다는 것을 꼭 잊지 말고 사용하도록 하자!
함수 안에서 선언한 변수의 효력범위에 대해 알아보기
함수 안에서 사용할 변수의 이름을 함수 밖에서도 동일하게 사용한다면 과연 어떻게 될까?
# vartest.py
a = 1
def vartest(a):
a = a +1
vartest(a)
print(a)
먼저 a라는 변수를 생성하고 1을 대입했다.
그리고 입력으로 들어온 값에 1을 더해 주고 결괏값은 리턴하지 않는 vartest 함수를 선언했다.
그리고 vartest 함수에 입력값으로 a를 주었다. 그 후 마지막으로 a의 값을 print(a)로 출력했다.
위와 같은 코드를 작성했을때 어떤 값이 출력될까?
vartest 함수에서 매개변수 a의 값에 1을 더했으므로 2가 출력될 것 같지만,
프로그램 소스를 작성해서 실행해 보면 결괏값은 1이 나온다.
그 이유는 함수 안에서 사용하는 매개변수는 함수 안에서만 사용하는 ‘함수만의 변수’이기 때문이다.
즉, def vartest(a)에서 입력값을 전달받는 매개변수 a는 함수 안에서만 사용하는 변수일 뿐, 함수 밖의 변수 a와는 전혀 상관없다는 뜻이다.
따라서 vartest 함수는 다음처럼 매개변수 이름을 hello로 바꾸어도 이전의 vartest 함수와 완전히 동일하게 동작하게 된다.
def vartest(hello):
hello = hello + 1
즉, 함수 안에서 사용하는 매개변수는 함수 밖의 변수 이름과는 전혀 상관없다는 의미이다.
# vartest_error.py
def vartest(a):
a = a + 1
vartest(3)
print(a)
위의 예시를 보게되면 더 분명하게 이해하기 쉬울 것이다.
위 코드 소스를 에디터로 작성해서 실행하면 어떻게 될까?
오류가 발생할 것이라고 생각했다면 위에서 설명한 내용을 모두 이해한 것이다.
vartest(3)을 수행하면 vartest 함수 안에서 a는 4가 되지만,
함수를 호출하고 난 후 print(a) 문장은 오류가 발생하게 된다.
그 이유는 print(a)에서 사용한 a 변수는 어디에도 선언되지 않았기 때문이다.
재차 강조하지만, 함수 안에서 선언한 매개변수는 함수안에서만 사용된다.
이것을 이해하는 것이 매우 중요하다.
함수 안에서 함수 밖의 변수를 변경하는 방법
그렇다면 vartest라는 함수를 사용해서 함수 밖의 변수 a를 1만큼 증가할 수 있는 방법은 없을까? 이 질문에는 2가지 해결 방법이 존재한다.
1. return 사용해서 변경하기
# vartest_return.py
a = 1
def vartest(a):
a = a +1
return a
a = vartest(a)
print(a)
위의 방법은 return을 사용하는 방법이다.
vartest 함수는 입력으로 들어온 값에 1을 더한 값을 리턴하도록 변경해주었다.
따라서 a = vartest(a)라고 작성하면 a에는 vartest 함수의 리턴값이 대입된다.
물론 vartest 함수 안의 a 매개변수는 함수 밖의 a 와 다르다.
2. global 명령어 사용해서 변경하기
# vartest_global.py
a = 1
def vartest():
global a
a = a+1
vartest()
print(a)
위의 방법은 global 명령어를 사용하는 방법이다.
위 예에서 볼 수 있듯이 vartest 함수 안의 global a 문장은 함수 안에서 함수 밖의 a 변수를 직접 사용하겠다는 뜻이다.
하지만 프로그래밍을 할 때 global 명령어는 사용하지 않는 것이 좋다.
함수는 독립적으로 존재하는 것이 좋기 때문이다.
외부 변수에 종속적인 함수는 그다지 좋지 않은 함수이기 때문에 되도록 global 명령어를 사용하는 방법보다 위의 return을 사용하는 방법이 좋다.
lambda 예약어
lambda는 함수를 생성할 때 사용하는 예약어로, def와 동일한 역할을 한다.
보통 함수를 한 줄로 간결하게 만들 때 사용한다.
우리말로는 ‘람다’라고 읽고 def를 사용해야 할 정도로 복잡하지 않거나 def를 사용할 수 없는 곳에 주로 쓰인다.
함수_이름 = lambda 매개변수1, 매개변수2, ... : 매개변수를_이용한_표현식
사용법은 위처럼 작성하여 사용할 수 있다.
>>> add = lambda a, b: a+b
>>> result = add(3, 4)
>>> print(result)
7
예시를 통해 작성한 코드이다.
(lambda로 만든 함수는 return 명령어가 없어도 표현식 결과값을 리턴한다.)
>>> def add(a, b):
... return a+b
...
>>> result = add(3, 4)
>>> print(result)
7
add는 2개의 인수를 받아 서로 더한 값을 리턴하는 lambda 함수이다.
위 예제는 def를 사용한 다음 함수와 하는 일이 완전히 동일하다.
여기까지 파이썬의 변수와 함수에 대해 알아봤습니다.
글을 작성하는데 참고한 글의 출처 : https://wikidocs.net/24
댓글남기기