값의 전달과 스코프(JavaScript, Python의 차이)

무슈랭·2024년 5월 10일
post-thumbnail

이번에 Python 기초 수업을 들으면서 지금까지 내가 지녔던 프로그래밍 기초 지식에 의문을 갖게 되었는데, 내가 알던 개념과 대치되는 흐름을 배웠기 때문이다. 실험과 검색을 통해 원인은 내가 알고 있던 JavaScript와 이번에 배운 Python 변수의 스코프 규칙의 차이 때문이란 걸 알았다.

JavaScript

let y = 1;
let z = 1;
console.log('top', y); // 1

function inc(y){
	y = y + 1;
	z = y + 1;
	console.log('one-y', y); // 2
	console.log('one-z', z); // 3
	last()
}

function last(){
	console.log('two-y', y); // 1
	console.log('tow-z', z); // 3
}

inc(y);
console.log('bottom-y', y); // 1
console.log('bottom-z', z); // 3

JavaScipt에서 y와 z는 전역변수로 설정되어있다.
inc(y)가 호출되면서 y가 인자로 전달 된다.
inc 함수 내부에서는 전달된 y의 값이 매개변수로 복사된다. y는 inc 함수의 매개변수가 되니까 inc 함수 안에서만 사용할 수 있다.
같은 이름의 y가 전역변수로 있지만 같은 스코프 안에 y가 지역변수로 우선시되기 때문이다.
지역변수 y에 y의 값인 1과 1을 더해 2가 할당된다.
z는 y + 1로 3이 할당된다. z는 전역변수의 값을 그대로 가져온거라 z에 할당할때 전역변수가 변경된다.
함수가 끝나면서 last()를 호출하고 y와 z를 출력하는데, 이때 y와 z는 각각 1, 3을 갖고 온다.
결과적으로 z만 변경된 것이다.

Python

x = 1
z = 1
print("top", x) // 1

def inc(x) :
    x = x + 1
    z = x + 1
    print("one-x ", x) // 2
    print("one-z", z) // 3
    last()

def last() :
    print('two-x', x) // 1
    print("tow-z", z) // 1

inc(x)
print("bottom-x", x) // 1
print("bottom-z", z) // 1

Python에서는 함수 내부에서 변수를 할당하면 해당 변수는 함수의 지역변수로 취급된다. 전역 변수를 함수로 가져와서 값을 변경할 수 있는 JavaScript와 달리 Python에서는 값을 할당하면 지역변수가 된다.
inc(x)가 호출되고 지역변수가 되는 x에 매개변수의 값 1과 1이 합인 2가 할당된다. z도 지역변수로 2 + 1인 3이 할당된다.
다음으로 last 함수가 호출되고 전역변수인 x와 z의 값이 출력된다.
결과를 보면 x와 z는 변경되지 않은 걸 확인할 수 있다.

파이썬에서 함수 안에서 전역변수의 값을 바꾸려면?

def inc(x) :
	global z
    x = x + 1
    z = x + 1
    print("one-x ", x) // 2
    print("one-z", z) // 3
    last()

global로 명시해주면 된다. 그러면 JavaScript와 마찬가지로 z가 전역변수로 취급되면서 값을 변경할 수 있다.
만약 global로 x를 명시한다면 에러가 나오는데 inc 함수 안에서의 x가 전역변수이자 매개변수로 중복되기 때문이다.

0개의 댓글