python

[기초 1-3] 함수(function)

jia.son 2022. 3. 27. 20:00

1. Call by value vs Call by reference

 

값에 의한 호출(call by value)

값에 의한 전달(pass by value) 는 동일한 개념이다

함수를 호출할 때, 값이 복사가 되고 호출한 곳에 영향을 끼치지 않는다.

숫자 객체는 변경될 수 없는 immutable object이다.

def change(num):
    num = num + 10
    print("change()내의 num 값:", num)
    print("change()내의 num 주소(id):", id(num))
    return num

n = 100
#id()는 매개변수 값으로 객체를 받아서 그 객체의 고유한 주소값을 반환해주는 함수이다.
print("호출 전 n의 주소(id):", id(n))
print("호출 전 n의 값", n)
x = change(n)
print("호출 후의 x의 값 :", x)
print("호출 전 x의 주소(id):", id(x))
print("호출 후의 n의 값 :", n)
print("호출 전 n의 주소(id):", id(n))

*https://pythontutor.com python tutor를 통해 코드를 쉽게 이해할 수 있다.

 

문자열에 대한 내용도 이전의 숫자형 객체와 동일하게 변경될 수 없는 immutable object 형태이다. 파이썬은 타 언어의 call by value의 개념과는 조금 다름 → 파이썬은 모든 타입을 "객체"로 판단하기 때문이다. 이런 특성이 존재하므로 call by objective 라고 칭한다. (값이 복사가 되어 저장됨) -> 주소는 동일하게 가르키지만 연산이 일어나면 새로운 객체 생성되어 주소가 달라짐.

def change(newName):
    newName += "jackson"
    print("change()내의 newName 값:", newName)
    print("change()내의 newName 주소(id):",id(newName))
    
name = "jia"
print("호출 전 name 값 :", name)
print("name 주소(id):",id(name))
getName = change(name)
print("호출 후 getName 값 : ", getName)
print("호출 후 getName 주소(id):",id(getName))
print("호출 후 name 값 : ", name)
print("name 주소(id):",id(name))

 

call by reference

함수를 호출할 때, 실질적인 주소값이 넘어가서 호출한 곳에 영향을 끼치는 형태

함수의 매개변수 값이 전부 객체인데 list, dictionary와 같은 mutable object, 즉 변경 가능한 객체이므로 call by objective-reference라고 한다.

def change(li):
    print("change()함수 내의 연산 전의 li의 값:", li)
    print("change()함수 내의 연산 전의 li의 주소:", id(li))
    li += [100, 200]
    print("change()함수 내의 연산 후의 li의 값:", li)
    print("change()함수 내의 연산 후의 li의 주소:", id(li))
    
list = ["a","hi",1,2,12]
print("list의 연산 전의 list의 값:", list)
print("list의 연산 전의 list의 주소:", id(list))
change(list)
print("list의 연산 후의 list의 값:", list)
print("list의 연산 후의 list의 주소:", id(list))

 

 

mutable object 중에는 list이외에 dictionary라는 타입이 있다. dictionary 타입의 형태는 키(key)와 값(value)→ {key : value}으로 이루어져 있다. dictionary의 key는 변경 불가능하고, value는 변경 가능함. dictionary의 call by reference가 성립되는 이유는 변경가능한 mutable object이기 때문에 가능하다.

call by objective-reference라고 칭함

def change(dictionary):
    print("change()함수 내의 연산 전의 dictionary의 값:", dictionary)
    print("change()함수 내의 연산 전의 dictionary의 주소:", id(dictionary))
    dictionary["weight"] = 50
    print("change()함수 내의 연산 후의 dictionary의 값:", dictionary)
    print("change()함수 내의 연산 후의 dictionary의 주소:", id(dictionary))

dic = {"name" : "손지아", "age":14, "height":170}

print("dic 내의 연산 전의 dictionary의 값:", dic)
print("dic 내의 연산 전의 dictionary의 주소:", id(dic))
change(dic)
print("dic 내의 연산 후의 dictionary의 값:", dic)
print("dic 내의 연산 후의 dictionary의 주소:", id(dic))

 

2. 지역변수(local variable)와 전역변수(global variable)

지역변수(local variable)

함수 안에 정의된 변수를 지역변수라고 하며, 지역변수의 범위(scope)은 함수 내에서만 사용이 되고 함수가 호출이 되고 종료가 되면 지역변수는 소멸된다.

def test():
    text = "python" # 지역변수 text에 문자열 할당
    print(text)     # 출력함수를 이용하여 text를 출력함.
# test()를 호출한 후,  "python"이라는 문자열을 출력하면서 리텅값은 없다.
test()

def test():
    text = "python" # 지역변수 text에 문자열 할당, 범위 test()내에서만 사용
    print(text)     # 출력함수를 이용하여 text를 출력함.
# test()를 호출한 후,  "python"이라는 문자열을 출력하면서 리텅값은 없다.
test()
# 출력함수에서 Exception has occurred: NameError 에러코드가 발생한다.
# 그이유는 바로 text 변수가 정의되지 않았다.
# 또한, test()에 있는 text라는 변수는 지역변수이므로 함수 호출 후 소멸된다.
print(text)

 

전역변수(global variable)

함수의 외부에 정의된 변수를 전역변수라고 한다.

파이썬은 전역변수를 다루는 형태가 타 언어들과 접근방식이 다르다. 전역과 지역이 명확하게 구분되어 있다.

def test():
    print(text)     #test()함수 내에 text라는 지역변수가 없을 때는 전역변수를 가져와서 사용함.
    
text = "python"     #전역변수인 text변수에 문자열 할당
test()

def test():
    #test()함수 내에 text라는 지역변수가 없을 때는 전역변수를 가져와서 사용함.
    # Exception has occurred: NameErrr에러가 발생함
    # test()를 호출한 시점에 전역변수 text가 정의되어있지 않아서 에러 발생
    print(text)     

test()    
text = "python"     #전역변수인 text변수에 문자열 할당

def test():
    #지역변수 text변수에 문자열 할당
    # 함수 내부에서 지역변수가 기본값이기 때문에 지역변수 출력
    text = "python"     
    print(text)         #지역변수 text값을 출력

text =  "java"      #전역변수 text에 문자열 할당
test()
#지역변수 text는 함수 호출 후 소멸되기때문에 전역변수 text의 문자열을 출력함
print(text)

'python' 카테고리의 다른 글

[ADsP]  (0) 2022.05.01
[Jupyter Notebook] Pandas (1. Series/Dataframe/Index)  (0) 2022.03.20
[Jupyter Notebook] Jupyter Notebook 준비  (0) 2022.03.13
[기초 1-2] 함수(function)  (0) 2022.03.13
[기초 1-1] 함수(function)  (0) 2022.03.06