안녕하세요, 온라인 코딩 스쿨 코드잇입니다.
이번에는 파이썬의 네임 스페이스에 관한 마지막 내용을 다루겠습니다.
이전 네임 스페이셔 1편, 2편에서 파이썬에는 모듈 범위에 해당하는 전역 네임 스페이스와 함수 또는 메소드의 범위에 해당하는 지역 네임 스페이스가 있다고 했습니다. 그리고 함수가 또 함수를 갖고 있는 경우에는 여러 지역 네임 스페이스가 있는 것이라고 배웠는데요.
그런데 이 두 가지 네임 스페이스보다 범위가 더 큰 네임 스페이스가 사실 하나 더 있습니다. 바로 빌트인(built-in) 네임 스페이스입니다. 빌트인 네임 스페이스는 파이썬의 기본 내장 함수와 기본 내장 예외들이 있는 공간으로 네임 스페이스 중에서 가장 최상위에 있는 네임 스페이스입니다.
그러니까 지역 네임 스페이스에도 없고, 전역 네임 스페이스에도 없는 이름은 마지막으로 빌트인 네임 스페이스에서 검색한다는 겁니다. 만약 이 빌트인 네임 스페이스까지도 찾아봤는데 없는 이름이라면 에러가 발생하게 됩니다.
그럼 빌트인 네임 스페이스에는 어떤 것들이 있을까요? 빌트인 네임 스페이스는 builtins라는 모듈이 갖고 있는 속성들에 해당하는데요. builtins 모듈은 __builtins__라는 이름으로 접근할 수 있습니다. builtins 모듈 안에 어떤 것들이 있는지 알아봅시다. dir라는 기본 내장 함수를 사용하면 모듈 안에 있는 속성들을 출력할 수 있는데요. 그러니까 이렇게 코드를 치면,
print(dir(__builtins__))
빌트인 네임 스페이스에 어떤 것들이 있는지 볼 수 있습니다.
출력 결과는 다음과 같습니다. 여러분이 쓰는 파이썬 버전에 따라 결과는 달라질 수도 있습니다.
['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', 'WindowsError', 'ZeroDivisionError', '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', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', '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', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
어떤가요. 빌트인 네임 스페이스에 정말 많은 것들이 있죠? 물론 전부 다 뭔지 정확히 알수는 없지만 방금 썼던 dir함수라든지, 자식 클래스인지 검사할 수 있는 issubclass함수라든지, 객체의 str 메소드를 호출하는 str함수 같은 것들이 눈에 보이네요.
혹시 여기 있는 것들이 무슨 뜻인지 자세히 알고 싶으신 분은 아래의 파이썬 공식 문서를 참조하세요.
https://docs.python.org/3/library/functions.html
https://docs.python.org/3/library/constants.html#built-in-consts
어떤 코드를 실행하든 파이썬이 항상 이 builtins 모듈을 코드에서 참조할 수 있는 상태로 만들어주기 때문에 우리는 따로 이 모듈을 import하지 않아도 빌트인 네임 스페이스에 있는 것들을 사용할 수 있는 겁니다.
그럼 만약 빌트인 네임 스페이스에 있는 함수와 같은 이름의 변수를 지정해버리면 어떻게 될까요?
일단
print(str(10))
이 코드는 10을 출력합니다.
하지만
str = “hello” print(str(10))
이렇게 쓰면 이런 에러가 뜹니다.
TypeError: 'str' object is not callable
왜 그런지 느낌이 오시나요? 지금 원래 우리가 알던 str함수는 아까 본 것처럼 빌트인 네임 스페이스에 있는 함수입니다. 그래서 여기 있는 걸 사용해야 하는데 지금 전역 지역 네임 스페이스에 str이라는 변수를 새로 또 하나 정의해버렸죠? 그럼 str(10) 이 부분이 실행될 때 함수 str이 아니라 변수 str이 사용되어 버립니다. 어떤 이름을 검색할 때 빌트인 네임 스페이스보다 전역 네임 스페이스가 먼저 참조되니까요. 그런데 전역 네임 스페이스에 있는 str은 함수가 아니라 그냥 변수입니다.
그러니까
TypeError: 'str' object is not callable
이렇게 “str 객체는 호출 가능한 객체가 아니다“라는 에러가 뜨는 거죠. 변수는 호출해서 실행할 수 있는 게 아니니까요. 왜 에러가 났는지 알겠죠? 그러니까 새로운 변수나 함수를 정의할 때는 혹시 빌트인 네임 스페이스에 있는 이름을 쓰고 있는 건 아닌지 주의하셔야 합니다. 그럴 가능성은 낮지만요.
자, 이제 네임 스페이스에 대해 다 배웠습니다. 어떤 변수나 함수를 이름으로 가리킬 때 그 검색 순서가 지역 네임 스페이스 -> 전역 네임 스페이스 -> 빌트인 네임 스페이스라는 것만 기억하시면 됩니다. 그럼 코딩하다가 실수할 일이 없을 거에요.
아참, 그리고 애초에 혼동을 막기 위해 서로 다른 네임 스페이스에 있는 변수나 함수는 서로 다른 이름을 지어주는 게 더 우선이라는 것도 잊지 마세요^^
파이썬 프로그래밍 기초에 대해 자세히 배우고 싶으면, 코드잇에서 72시간 무료로 체험해보세요!