이름공간

소 개

이름공간 namespace이란 무엇인가? 자주 이런 질문을 듣는다. 음, 그것은 일종의 설명하기 어려운 것이다. 그것이 특별히 복잡해서가 아니라, 오히려 모든 언어들이 그것을 다르게 처리하기 때문이다. 개념은 대단히 직설적이어서, 이름공간은 프로그램안에 있는 공간 혹은 지역으로, 거기에 이름이(변수, 클래스 등등이) 존재한다.

그것들이 나타난 이유는 (베이직과 같은) 초기의 프로그래밍 언어가 전역변수 Global Variables만을 가졌기 때문에, 다시 말하면, 그 전역변수들은 프로그램 전체를 통하여서 - 심지어는 함수안에서 조차 - 보여질 수 있었기 때문이었다. 이것때문에 거대한 프로그램의 유지가 어려웠는데 프로그램의 다른 부분은 그것을 인식하지도 못하는데 프로그램의 한 부분이 한 변수를 너무 쉽게 변경할 수 있었기 때문이었다. - 이것은 부작용side-effect이라고 불리웠다. 이문제를 해결하기 위하여, (현대의 베이직을 포함하여) 나중의 언어들은 이름공간이라는 개념을 도입하였다. (C++은 이것을 최대한 받아들여서 프로그래머가 자신만의 이름공간을 프로그램의 어느 곳에나 만들수 있도록 하였다. 이것은 라이브러리를 만드는 사람들에게는 대단히 유용하다. 그들은 다른 공급자가 제공한 라이브러리와 조합될 때 함수의 이름을 유일하게 유지하기를 원한다.)

파이썬의 접근방법

파이썬에서 모든 모둘은 자신만의 이름공간을 생성한다. 그러한 이름에 접근하기 위해서 우리는 그 이름앞에 모듈의 이름을 명시적으로 붙이던가 혹은 우리가 사용하기를 원하는 그 이름을 우리의 모듈 이름공간에 수입하여야만 한다. 새로운 것은 없다, 우리는 이미 sys모듈과 string모듈로 그렇게 하고 있는 중이다. 어떤 면으로 클래스 정의 또한 자신만의 이름영역을 생성한다. 그러므로, 클래스의 메쏘드 혹은 속성에 접근하기 위해서는, 우리는 그 실체 변수의 이름을 사용하던가 혹은 클래스이름을 먼저 사용할 필요가 있다.

파이썬에는 단지 3개의 이름공간이 있다 (혹은 영역 scopes):

  1. 지역 영역 - 함수 혹은 메쏘드 안에서 정의된 이름
  2. 모듈 영역 - 파일안에서 정의된 이름
  3. 내장 영역 - 파이썬 자체에서 정의된 이름으로 항상 사용가능하다.

지금까지는 그런데로 괜찮다. 이제 다른 이름공간에 있는 변수들이 같은 이름을 가질 때 이것은 어떻게 공존하는가? 혹은 현재의 이름공간안에 없는 이름이 참조될 때는? 먼저 이전의 상황을 살펴보자: 만약 한 함수가 X라고 부르는 변수에 참조되고 그리고 그 함수안에 (즉 지역 영역에) 또 다른 X 가 존재한다면 그러면 앞의 것이 바로 파이썬에 의하여 보여지고 사용될 변수이다. 이름의 충돌을 피하는 것은 프로그래머의 일로서 같은 이름을 가진 모듈 변수와 지역 변수 모두가 같은 함수에서 요구되지 않도록 해야한다 - 지역 변수는 전역변수를 덮을 것이다.

일반적으로 여러분은 '전역' 서술문의 사용을 최소화해야 한다. 매개변수로서 변수를 넘겨 받고 그리고 변경된 변수를 반환하는 것이 보통 더 좋다.

현재의 지역 이름공간안에 없는 이름이 참조될 때, 두번째 요점은 다음과 같이 해결된다: 그 함수는 지역 이름공간안을 살펴보고, 만약 찾을 수 없다면 그러면 모듈 영역을 조사하고 만약 거기에도 없다면 내장 영역을 살펴본다. 이것에 대한 유일한 문제점은 우리가 값을 외부의 변수에 할당하고자 원할 때이다. 일반적으로 이것은 새로운 변수 이름을 생성할 것이다, 그러나 우리는 그러한 일이 일어나질 않기를 원하고 그래서 우리는 그 이름의 지역 버젼을 생성하지 않은 것을 확인하기 위하여 한번 더 그것을 전역(global)으로 지정해야만 한다.

우리는 이 예제에서 이 모든 것이 작동하는 것을 볼 수 있다. ( 이것은 순수히 그 요점을 예시하는 것이다!):

# variables with module scope
W = 5
Y = 3

#parameters are like function variables
#so X has local scope
def spam(X):
   
   #tell function to look at module level and not create its own W
   global W

   Z = X*2 # new variable Z created with local scope
   W = X+5 # use module W as instructed above

   if Z > W:
      # print is a 'builtin-scope' name
      print "2 x X is greater than X + 5"
      return Z
   else:
      return Y # no local Y so uses module version

이에 우리가 sys 와 같은 모듈을 수입할 때 우리는 sys 라는 이름을 지역적으로 사용가능하게 하는 것이며 그리고 우리는 그 이름을 우리가 알고 있는 것으로 간주함으로써 sys 모둘의 이름공간안에 있는 이름들에 접근할 수 있다.
우리가 다음과 같이 한다면:

from sys import exit

우리는 exit 함수를 지역 이름공간에만 가져올 수 있다. 우리는 다른 어떤 sys 이름도 사용할 수 없으며, 심지어는 sys 자체도 사용할 수 없다.

그리고 베이직 역시

베이직은 파이썬과 정 반대의 접근법을 취하여 (오래된 베이직 프로그램들과 호환성을 위하여) 기본 설정으로 모든 변수들을 전역적으로 만든다. 그러나 프로그래머가 함수안에서 지역 LOCAL변수도 역시 만들수 있도록 해준다.

Tcl

내가 아는 한 티클에서는 이름영역을 제어하지 않는다. 아마도 프로그램을 파스하는 티클의 독특한 방식때문에 그럴 것이다. 어떤 경우에도 겉보기에 모든 변수들은 자신을 둘러싸고 있는 직접적인 환경에 대하여 지역적이다 - 파일 수준의 변수는 그 파일안에 있는 명령어들에게만 보여지며 프로시저 변수는 프로시져안에서만 보여진다. 그 두 이름공간 사이의 통신을 위해서 여러분은 그 값들을 매개변수로 넘겨 받아야만 한다.


Previous  Next  Contents


이 페이지에 대하여 질문 혹은 제안사항이 있으면 다음 주소로 나에게 메일을 보내라: agauld@crosswinds.net