def adder(n1,n2):
r = n1 + n2
return r
print(adder(3,4))
(함수 복습) 전달되는 값을 매개변수 n1, n2로 받고 r에 저장된 값을 반환함
for i in (1,3,5,7,9):
print(i, end = ' ')
지금까지 함수들은 대부분 이해를 하고 만들었지만 [end = ' ']은
[print는 무언가를 출력하면 바로 개행을 해버린다. 하지만 end = ' '를 쓰면 개행 대신 따옴표 안의 값을 넣는다]
라는 식으로 이해를 하는 게 아니라 어떤 현상이 일어나는지만 알고 있었다.
end를 이해하기에 앞서서 먼저 이해할 것이 있다.
def who_are_you(name, age):
print("이름",name)
print("나이",age)
첫 번째로 전달한 값이 첫 번째 매개변수에 저장되고 두 번째로 전달한 값은 두 번째 매개변수에 저장된다.
우리는 지금까지 위의 규칙만 가지고 사용을 해왔고, 매개변수를 따로 불러서 값을 저장하지 않았다
즉 위의 함수를 사용할 때 who_are_you("이용진",24) 이런식으로만 써왔던 것이다.
하지만 who_are_you(name = "이용진", age = 24)
이런식으로 매개변수의 이름을 거론해도 된다.
만약 이렇게 매개변수의 이름을 직접 거론할 때는
who_are_you(age = 24, name = "이용진") 이렇게 순서를 바꿔도 상관없다.
위의 글을 이해했다면,
출력의 기능을 가진 print 함수의 매개변수 중 하나의 이름이 end라는 판단이 가능하게 된다.
[end = ' ']는 end라는 매개변수에 ' '을 전달하라는 뜻
즉 print는 end라는 매개변수를 통해 전달된 내용을 마지막에 덧붙여준다는 것을 알게 된다.
print(1,2,3,sep = ',')
print함수의 매개변수 중 하나인 sep는 separate의 줄임말이며 분리라는 뜻이다.
총 3개의 값이 출력되는데 그 사이사이에 sep으로 전달된 ', '을 출력하게 된다.
앞에서 함수의 호출하는 과정에서 매개변수의 값을 지정했었다.
하지만 함수의 정의에서 지정할 수도 있다.
def who_are_you(name,age=0):
print("이름: ",name)
print("나이: ",age)
이렇게 함수의 정의에서 매개변수에 값을 지정할 수도 있고, 이런 것을 디폴트 값이라고 한다.
위의 코드는 0을 age라는 매개변수에 저장하겠다는 뜻인데,
함수를 호출하는 사람이 age의 값을 지정하지 않는다면 디폴트 값인 0이 자동으로 지정된다는 의미이다.
즉 정리하면, 함수를 호출할 때 age의 값을 전달하지 않으면 디폴트 값인 0이 age에 들어간다.
[값을 지정하지 않으면 이걸 기본으로 할게~ ]라는 뜻
def who_are_you(name,age=0):
print("이름: ",name)
print("나이: ",age)
who_are_you("이용진")
이런 식으로 매개변수 name에 들어갈 값만 입력하고 매개변수 age에 들어갈 값을 입력하지 않는다면,
이름: 이용진
나이: 0
이 출력된다는 소리이다.
def who_are_you(name,age=0):
print("이름: ",name)
print("나이: ",age)
who_are_you("이용진",24)
만약 이렇게 매개변수 각각에 값을 잘 넣으면
이름: 이용진
나이 : 24
굳이 디폴트값이 나올 필요가 없으니, 입력된 값이 제대로 잘 나온다.
[매개변수 참조 관계]
def func(s):
s[0] = 0
s[-1] = 0
st = [1,2,3]
func(st)
print(st)
지금까지 배워왔던 대로 생각해 본다면
func 함수의 매개변수 s에 st에 저장된 [1,2,3]을 보내고 s[0]과 s[-1]의 값을 수정했을 때
st를 출력하면 [1,2,3]이 그대로 나와야 한다. 왜냐하면 수정된 것은 매개변수 s이기 때문이다.
하지만 위의 코드를 실행시키면
매개변수 s에 전달된 값을 수정했음에도 불구하고 st가 수정되어서 출력된다. 왜일까???
초반에 배웠던 이름표 붙이기 관점에서 봐야 한다.
st = [1,2,3]은
[1,2,3]이라는 리스트를 메모리 공간에 저장한다. 그리고 그 메모리 공간에 st라는 이름표를 붙인다.
이후 함수를 호출하면 매개변수 s에 st를 전달하고 s = st가 된다.
즉 st가 가리키는 [1,2,3]이라는 영역에 s라는 이름표를 추가로 붙이는 것이고,
[1,2,3]라는 리스트는 st라는 이름도 갖고 s라는 이름도 가지게 된다는 소리이다.
따라서 s의 값을 변경, 수정하면 st를 불렀을 때 변경된 값이 출력된다
함수 안에서 값을 변경하거나 수정할 때는 그것이 원본에도 영향을 끼친다는 것을 인지해야 한다.
그렇게 영향을 미치는 이유는 이름표 붙이기에 비밀이 있다!
함수의 인자 전달 방식에는 Call by value와 Call by reference가 있다
call by value는 변수를 복사한 값을 전달하는 방식으로, 예를 들면
변수 a가 있고 함수 def1이 있을 때, def1(a)에서 전달받은 a는 a자체(주소 값)가 아니라 a의 복사 값(레플리카)이다.
따라서 함수 안에서 a를 바꿔도 원본 변수 a는 변하지 않는다.
call by reference는 인자로 받은 변수의 주소 값을 전달하는 방식으로, 예를 들면
변수 a가 있고 함수 def2가 있을 때, def2(a)에서 전달받은 a는 원본 전역 변수 a의 주소 값이다.
따라서 함수 안에서 a를 바꾸면 원본 변수 주소 값으로 타고 들어가서 원본 자체를 바꾼다
파이썬은 위의 경우처럼 주소 값 참조 또는 값 복사의 개념과는 다르다.
파이썬에서 변수는 특정 메모리 공간을 할당받은 박스 개념이 아니라, 객체에 붙여진 이름표이다.(1일 차 이름표 붙이기 참고)
파이썬은 전역인지 지역인지 영역에 따라 변수들의 정보를 저장하는 공간이 따로 있다
전역 변수를 함수에서 인자로 받아오더라도 함수 내에서는 지역변수에 불과하다는 뜻이다.
함수 내에서 이름표를 떼서 다른 객체에 붙인다고 하더라도, 그 이름표는 함수 내에서만 사용하는 이름표일 뿐이다.
list1(이름표) , [1,2,3,4](객체)
list1 = [1,2,3,4]을 함수 내에서 [5,6,7,8]이라는 새로운 객체랑 묶어도 함수 호출이 끝나면 list1은 그대로 [1,2,3,4]이다.
하지만 이름표만 떼고 붙이는 게 아니라 객체를 직접 조작하는 경우는 다르다.
list1[0] = 5처럼 객체 내의 요소를 조작하는 경우 함수 호출이 끝나서 지역 이름표(변수)가 전역 이름표(변수)로 바뀐다고 하더라도 객체가 변했으므로 list1은 [5,2,3,4]이다..
객체 자체를 바꾸려면 앞에서 배웠던 것처럼 객체가 mutable 해야 한다.
immutable 한 튜플은 당연히 변경할 수 없고
mutable 한 리스트, 딕셔너리 등은 변경할 수 있다.
'프로그래밍 언어 > 파이썬 기초' 카테고리의 다른 글
파이썬 딕셔너리 (0) | 2023.06.04 |
---|---|
파이썬 모듈 import (0) | 2023.05.23 |
파이썬 튜플,range (0) | 2023.05.23 |
파이썬 for문,while문 (0) | 2023.05.23 |
파이썬 bool형,if문, 논리연산자 (0) | 2023.05.22 |