goodthings4me.tistory.com
효율적 개발로 이끄는 파이썬 실천 기술 - 이름공간(namespace), 스코프
(참고용으로 사용할 부분만 간략하게 정리)
이름공간(namespace)
- 이름과 객체의 매핑, 특정한 하나의 이름이 통용될 수 있는 범위
- 이름공간이 다르면 같은 이름이 다른 객체를 참조할 수 있다
- 이름공간의 종류 : 전역 이름공간(모듈별), 지역 이름공간(함수 및 메서드별), 빌트인 이름공간(내장함수, True/False, None 등)
- 이름공간 생성 시점 : 내장객체 이름공간은 파이썬 실행 시, 모듈별 전역 이름공간은 해당 모듈이 최초에 로딩될 시, 로컬 이름공간은 변수 호출 시 생성되며, 함수에서 벗어나면 그 이름공간은 삭제됨
- 클래스 정의 시 로컬 이름공간이 생성되고, 클래스 변수와 메서드는 이 이름공간에 속하고, 만들어진 클래스 객체는 이 이름공간을 참조함
스코프(scope)
- 점(.)을 붙이지 않고 변수명만을 지정해 호출하면 파이썬은 직접 접근할 수 있는 이름공간부터 해당 이름을 가진 객체를 검색하는데, 직접 접근 가능한 영역을 스코프라고 함
- 스코프는 텍스트 상에서의 영역이며, 코드를 작성한 단계에서 정적으로 결정됨
- 종류(좁은 순) : 로컬 스코프, 인클로징 스코프(nested), 전역 스코프, 빌트인 스코프
- 이름 검색은 좁은 스코프에서 넓은 스코프 순으로 하며, 가장 먼저 발견한 이름의 객체를 참조하고, 마지막까지 발견 못하면 NameError 예외 발생함
# 로컬 스코프 - 함수(메서드 포함) 내로 제한, 함수 내 변수(로컬변수)의 참조 범위
def f(v):
print(v) # 함수의 인수도 로컬 스코프
v = f'f_function'
print(v)
print(locals()) # 내장함수 locals() : 로컬 변수 목록 얻음
f(20)
# 컴프리헨션도 로컬 스코프
c = [value for value in range(1)]
print(c)
#print(value) # NameError: name 'value' is not defined
# 모듈의 최상위 레벨에서 내장함수 locals()는 전역 스코프와 일치
[결과]
20
f_function
{'v': 'f_function'}
[0]
# 전역 스코프 - 모듈의 최상위 레벨 스코프 의미 (이 스코프에서 정의되어 있는 변수는 전역 변수)
# 다른 모듈에서 정의한 값은 참조 시 명시적 임포트 필요(스코프가 다르므로)
# 함수나 클래스, 메서드는 반드시 모듈 내부에 정의함 => 같은 모듈 내에서는 항상 모듈의 전역변수 참조 가능
x = 100
def f():
print(x) # 전역 변수 참조
f()
def g():
x = f'f_function' # 지역 변수
print(x)
g()
print(x)
# 함수 내에서 전역변수 참조 후 그 함수 내에 같은 이름의 로컬변수 정의 불가 (전역변수 덮어쓰기 방지)
def fn():
print(x)
#x = f'fn_function' # UnboundLocalError: local variable 'x' referenced before assignment
fn()
# 전역 변수 덮어쓰기
x = 100
def fg():
global x # 전역변수임을 명시 후 업데이트 함
x = '200'
print(x)
fg()
print(x) # 전역변수 값 업데이트됨
[결과]
100
f_function
100
100
200
200
# 전역변수가 컨테이너 객체이고 그 컨테이너 객체가 유지하는 값을 덮어쓸 때는 global 문이 필요없음(참조 수행 후 값 업데이트)
# x[0] = 2 에서 객체 'x' 먼저 검색 후 객체의 인덱스 0의 값 업데이트 함
x = [0, 1]
def f():
x[0] = 2
print(x)
f()
print(x)
# 전역변수 치환 기능은 가독성 및 유지보수성 저하 원인(사용 시 주의)
[결과]
[0, 1]
[2, 1]
# 빌트 인 스코프 - 내장 객체의 스코프이고, 가장 마지막에 검색되는 스코프
# 이 스코프에 있는 내장 객체는 builtins 모듈에 정의되어 있고,
# 전역변수 __builtins__로 이 모듈에 대한 참조를 얻을 수 있음
#print(dir(__builtins__))
cnt = 1
for i in dir(__builtins__):
print(i, end=', ')
cnt += 1
if cnt % 7 == 0:
print()
[결과]
ArithmeticError, AssertionError, AttributeError, BaseException, BlockingIOError, BrokenPipeError,
BufferError, BytesWarning, ChildProcessError, ConnectionAbortedError, ConnectionError, ConnectionRefusedError, ConnectionResetError,
DeprecationWarning, EOFError, Ellipsis, EnvironmentError, Exception, False, FileExistsError,
FileNotFoundError, FloatingPointError, FutureWarning, GeneratorExit, IOError, ImportError, ImportWarning,
IndentationError, IndexError, InterruptedError, IsADirectoryError, KeyError, KeyboardInterrupt, LookupError,
MemoryError, ModuleNotFoundError, NameError, None, NotADirectoryError, NotImplemented, NotImplementedError,
OSError, OverflowError, PendingDeprecationWarning, PermissionError, ProcessLookupError, RecursionError, ReferenceError,
ResourceWarning, RuntimeError, RuntimeWarning, StopAsyncIteration, StopIteration, SyntaxError, SyntaxWarning,
SystemError, SystemExit, TabError, TimeoutError, True, TypeError, UnboundLocalError,
UnicodeDecodeError, UnicodeEncodeError, UnicodeError, UnicodeTranslateError, UnicodeWarning, UserWarning, ValueError,
Warning, ZeroDivisionError, __IPYTHON__, __build_class__, __debug__, __doc__, __import__,
__loader__, __name__, __package__, __spec__, abs, all, any,
ascii, bin, bool, breakpoint, bytearray, bytes, callable,
chr, classmethod, compile, complex, copyright, credits, delattr,
dict, dir, display, divmod, dreload, enumerate, eval,
exec, execfile, filter, float, format, frozenset, get_ipython,
getattr, globals, hasattr, hash, help, hex, id,
input, int, isinstance, issubclass, iter, len, license,
list, locals, map, max, memoryview, min, next,
object, oct, open, ord, pow, print, property,
range, repr, reversed, round, runfile, set, setattr,
slice, sorted, staticmethod, str, sum, super, tuple,
type, vars, zip,
# 클로저(closure) - 작성 시 환경을 기억하는 함수 객체의 한 종류
# 즉, 자신이 만들어졌을 때의 환경(바깥쪽 스코프)에 있는 변수에 대한 참조 유지
def counter():
count = 0
def _increment():
nonlocal count
count += 1
return count
return _increment # 함수 객체 반환
# 함수 안의 로컬변수는 마지막 실행 시점에서 사라지지만,
# 클로저 함수 객체는 자신이 정의된 시점에 바깥쪽 스코프에 정의되어 있던 변수(count)에 대한 참조를 계속 유지함
# 즉, _increment() 함수 실행 시마다 로컬 변수 count 값이 증가함
cnt1 = counter()
print(cnt1) # function counter.<locals>._increment at...
print(cnt1())
print(cnt1())
[결과]
<function counter.<locals>._increment at 0x7f0056a0c440>
1
2
[참고/출처] 효율적 개발로 이끄는 파이썬 실천 기술 - 파이썬에 숨겨진 힘을 이용해 개발 효율을 높이자!
'코딩 연습 > 코딩배우기' 카테고리의 다른 글
[Python] 폴더(디렉토리) 만들기 - mkdir() or makedirs() (0) | 2021.06.22 |
---|---|
파이썬 실천 기술 #06 - 내장함수와 특수메서드(스페셜 메서드) (0) | 2021.06.12 |
파이썬 실천 기술 #04 - 클래스와 인스턴스 (1) | 2021.05.26 |
파이썬 실천 기술 #03 - 함수 (0) | 2021.05.25 |
파이썬 실천 기술 #02 - 데이터 구조 (0) | 2021.05.20 |
댓글