[TIL]Python. Scope

여주링·2020년 11월 25일
0

Python

목록 보기
10/15

Scope(유효범위)

개념과 종류

Scope은 범위라는 뜻으로 프로그래밍 언어에서 scope은 어떠한 객체(변수, 함수)등이 적용될수 있는 범위를 의미한다(범위를 벗어나면 해당 객체는 사용될 수 없다)
파이썬 범위 해석은 LEGB(Local, Enclosing, Global, Built-in)에 기초한다

  • Local Scope(지역 스코프)
  • Enclosed Scope
  • Global Scope(전역 스코프)
  • Built-in Scope

(Local Scope이 가장 범위가 제한적이고 built-in scope이 가장 범위가 광범위함)

파이썬의 scope(유효범위)는 함수를 통해서 생성됩니다.
유효범위와 함께 알아야 하는 것이 전역변수와 지역변수입니다. 전역변수는 코드 전체에서 다 접근할 수 있는 변수를 뜻합니다. 지역 변수는 함수 내에서만 접근할 수 있는 변수라고 말할 수 있습니다.

전역변수(Global Scope)와 지역변수(Local Scope)에 대한 이해

1.지역변수(Local Scope) : 함수 내부에 선언된 변수나 함수가 이에 해당된다

2.전역변수(Global Scope) : 말 그대로 함수나 클래스, 객체 내부에 선언 된 변수나 함수가 아닌 그 밖에 선언된 변수나 객체 scope를 뜻한다. 선언된 지점에 대한 동일 지역 및 그 하위까지 모두 접근이 가능하다.

a = 1
def scope():
    a = 2
    print(a)

scope() # 2
print(a) # 1

scope함수와 print(a)의 결과는 서로 다르게 나타난다.
즉,둘은 이름은 같지만 다른 a로 scope 함수 밖의 print() 함수는 함수 내부로 들어가 값을 찾지 못한다. 그래서 전역변수인 a에 접근해서 값을 출력했다

위의 경우 외부의 a=1를 전역변수. 내부의 a=2를 지역변수라고 한다.

Enclosed Scope 와 Built-in Scope의 개념

  1. Enclosing Scope
    중첩함수가 있을때 적용되는 scope로, 부모 함수에서 선언된 변수는 중첩함수 안에서도 유효한 범위를 가지고 있습니다.
def enclosing_scope(): 
	enclosing_var = 2 
	def inner_func(): 
		inner_var = 3 
		print(enclosing_var * inner_var) # 6이 나온다 

inner_func() 
print(inner_var)

다시 말해 외부 함수에서 선언된 변수나 함수는 그 내부함수에 까지 영향을 미치게 되는 것이다.

  1. Built-in Scope
    어떤 python 파일을 작성하든지 간에 항상 포함되는 가장 광범위한 scope라고 보면 된다. python 설치 파일 안에 바로 내장 되어 있다. 별다른 선언없이 실행되는 len(), input(), print() 와 같은 python 내장 함수등이 해당 범위에 해당된다.

Shadowing

파이썬은 변수나 함수의 정의를 찾을때 다음 순서의 scope들 안에서 찾는다

Local => Enclosing => Global => Built-in

즉 가장 좁은 유효범위 부터 시작 해서 넓은 범위로 나아가며 사용되는 변수나 함수의 정의를 찾음.그러므로 만일 동일한 이름의 변수들이 서로 다른 scope에서 선언이 되면 더 좁은 범위에 있는 변수(혹은 함수)가 더 넓은 범위에 있는 변수를 가리는 (shadowing)효과가 나타난다.

조금더 심화해서 이해하기

a = 1
def scope():
    print(a)

scope()

외부에는 a값이 정의되어 있으나 내부는 X.
함수내부에서 값(여기서는 a)을 찾지못하면 한 단계씩 더 위로 올라가면서(그 위가 전역이라면 전역에서 찾고, 다른 함수 내부에 있다면 자신을 포함하고 있는 함수에서 찾습니다.) 값을 계속 찾게됨

a = 1
def scope():
    def scope2():
        print(a)
    scope2()

scope()

위의 경우에도 scope2자기범위에서 a가 지정되있는지 찾아봄 -> 없으니 scope1을 참고->없네.. 자, 전역변수를 빌려오자
가 되는것

함수 내부에서 전역변수를 수정해볼까

pyhton
a = 1
def scope():
    a = a + 5
    
scope()
#UnboundLocalError: local variable 'a' referenced before assignment

전역변수의 값을 찾아내지만 변경하려고 하면 에러가 난다.
해결방법은

a = 1
def scope():
    global a
    a = a + 5
    print(a)

scope() #6
print(a) #6

Global 변수명 를 입력해주면 전역변수를 가르킨다는걸 의미. 그리고 함수가 실행되면서 전역변수a의 값이 바뀌게 된다.
이런식으로 전역변수의 경우 갑자기 다른 함수에 의해 변경되는 경우가 있고, 에러가 발생할 확률이 높다. 따라서 전역변수를 지양하는 것이 좋음

정적스코프와 동적스코프

  • 정적스코프 : 선언된 시점에서 유효범위를 갖는 것
  • 동적스코프 : 실행되는 시점에서 유효범위를 갖는 것
a = 1

def scope():
    a = 5
    scope2()

def scope2():
    print(a)

scope()

scope()함수를 통해서 실행된 scope2()함수의 값은 5일까 1이까?
파이썬은 정적스코프를 가집니다. 즉 실행될 때 a = 5이지만 자신이 선언될 때는 1이었기 때문에 1이라는 값을 출력한다

profile
🌱Backend Developer👩‍💻

0개의 댓글