17. 파이썬 모듈




1 이름 공간


  • 이름 공간 또는 스코프 (Naming Space or Scope): 이름이 존재하는 장소. 파이썬은 실행 시간에 각 이름들을 적절한 이름 공간에 넣어 관리한다.
  • 이름 공간(스코프)의 종류
    • 지역(Local): 각 함수 내부
    • 전역(Global): 모듈 (파일) 내부
    • 내장(Built-in): 파이썬 언어 자체에서 정의한 영역
  • 변수가 정의되는 위치에 의해 변수의 스코프가 정해짐
    • 파이썬에서 변수의 정의
      • 변수가 l-value로 사용될 때
  • 변수가 r-value로 사용될 때 해당 변수의 값을 찾는 순서 규칙
    • L --> G --> B

image

1-1 지역변수와 전역변수

  • 변수의 스코프는 해당 변수가 l-value로서 정의되는 위치에 따라 달라짐
  • 변수가 함수 내에서 정의되면 해당 함수의 지역 변수가 된다.
In [1]:
# g, h는 전역 변수
g = 10
h = 5

def f(a): # a는 지역 변수
    h = a + 10 # h는 지역, 새로 l-value로 정의했음
    b = h + a + g # b도 지역, g는 r-value이므로 기존 값을 참조 - 전역 변수
    return b

print(f(h)) # 함수 호출시에 사용되는 변수는 해당 위치의 스코프에서 값을 찾음 - 전역 변수
print(h) # 전역 변수 h는 변함 없음
30
5
  • 함수 내부에서 전역 변수를 직접 사용하고자 할 때
    • global 키워드 활용
In [3]:
h = 5

def f(a):      # a는 지역
    global h   # h 변수를 전역이라고 미리 선언함
    h = a + 10 # h는 l-value로 정의되더라도 미리 선언된 내용 때문에 전역 변수
    return h

print(f(10))
print(h)        # 전역 변수 h 값이 함수 내에서 변경되었음
20
20
  • [주의] 동일 함수 내에서 동일한 변수가 지역변수와 전역변수로 동시에 활용될 수 없음
    • 함수 내에서 정의되는 변수는 지역 변수로 간주
    • 지역 변수로 선언되기 이전에 해당 변수를 사용할 수 없음
In [4]:
g = 10

def f():
    a = g      # r-value로 사용되는 g는 전역 변수
    g = 20     # l-value로 정의되는 g는 지역 변수
    return a

print(f())
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-4-b9cfd4ba6eab> in <module>()
      6     return a
      7 
----> 8 print(f())

<ipython-input-4-b9cfd4ba6eab> in f()
      2 
      3 def f():
----> 4     a = g      # r-value로 사용되는 g는 전역 변수
      5     g = 20     # l-value로 정의되는 g는 지역 변수
      6     return a

UnboundLocalError: local variable 'g' referenced before assignment
In [5]:
g = 10

def f():
    global g    # g는 전역 변수로 선언됨
    a = g       # a는 지역 변수, g는 전역 변수
    g = 20      # g는 전역 변수
    return a

print(f())
print(g)
10
20

1-2 특정 공간의 이름 목록 얻기

  • 이름(Name)
    • 변수 (객체) 이름
    • 함수 이름
    • 클래스 이름
    • 모듈 이름
  • dir(): 함수가 호출된 스코프에서 정의되어 있는 모든 Name들을 문자열 리스트로 반환한다.
  • dir(object): object이 지니고 있는 모든 Name들을 문자열 리스트로 반환한다.
In [5]:
print(dir())
['In', 'Out', '_', '_4', '__', '___', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '_dh', '_i', '_i1', '_i2', '_i3', '_i4', '_i5', '_ih', '_ii', '_iii', '_oh', '_sh', 'exit', 'f', 'g', 'get_ipython', 'quit']
In [7]:
l = []
print(dir(l))
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

1-3 함수의 중첩 영역(Nested Scopes) 지원

  • Nested Scope: 함수 안에 정의되어 있는 함수 내부
    • 가장 안쪽의 스코프부터 바깥쪽의 스코프쪽으로 변수를 찾는다.
In [10]:
x = 2
def F():
    x = 1
    def G():
        x = 20
        print(x)
    G()
F()
20
In [11]:
x = 2
def F():
    x = 1
    def G():
        x = 20
        print("G():", x)
    G()
    print("F():", x)
F()
print("Global:", x)
G(): 20
F(): 1
Global: 2
In [14]:
x = 2
def F():
    x = 1
    def G():
        global x
        x = 20
        print("G():", x)
    G()
    print("F():", x)
F()
print("Global:", x)
G(): 20
F(): 1
Global: 20

2 모듈의 정의


  • 모듈: 파이썬 프로그램 파일로서 파이썬 데이터와 함수등을 정의하고 있는 단위
    • 서로 연관된 작업을 하는 코드들을 묶어서 독립성을 유지하되 재사용 가능하게 만드는 단위
    • 모듈을 사용하는 측에서는 모듈에 정의된 함수나 변수 이름을 사용
  • 모듈의 종류
    • 표준 모듈
      • 파이썬 언어 패키지 안에 기본적으로 포함된 모듈
      • 대표적인 표준 모듈 예
        • math, string
    • 사용자 생성 모듈
      • 개발자가 직접 정의한 모듈
    • 써드 파티 모듈
      • 다른 업체나 개인이 만들어서 제공하는 모듈

2-1 모듈은 어디에 저장되는가

  • 모듈이 정의되고 저장되는 곳은 파일
    • 파일
      • 모듈 코드를 저장하는 물리적인 단위
    • 모듈
      • 논리적으로 하나의 단위로 조직된 코드의 모임
  • 파이썬 모듈이 정의되는 파일의 확장자: .py
  • 다른 곳에서 모듈을 사용하게 되면 해당 모듈의 .py는 바이트 코드로 컴파일 되어 .pyc로 존재한다.

2-2 사용자 모듈 만들기와 호출하기

In [9]:
#File: mymath.py
mypi = 3.14

def add(a, b):
    return a + b

def area(r):
    return mypi * r * r
  • 모듈 이름은 해당 모듈을 정의한 파일 이름에서 .py를 제외한 것
    • 모듈을 불러오는 키워드: import
  • 모듈에서 정의한 이름 사용하기
In [11]:
import mymath

print(dir(mymath))    # mymath에 정의된 이름들 확인하기
print(mymath.mypi)    # mymath 안에 정의된 mypi를 사용한다
print(mymath.area(5)) # mymath 안에 정의된 area를 사용한다
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'add', 'area', 'mypi']
3.14
78.5

2-3 모듈을 왜 사용하는가?

  • 함수와 모듈
    • 함수: 파일 내에서 일부 코드를 묶는 것
    • 모듈: 파일 단위로 코드들을 묶는 것
      • 비슷하거나 관련된 일을 하는 함수나 상수값들을 모아서 하나의 파일에 저장하고 추후에 재사용하는 단위
  • 모듈 사용의 이점
    • 코드의 재사용
    • 프로그램 개발시에 전체 코드들을 여러 모듈 단위로 분리하여 설계함으로써 작업의 효율을 높일 수 있음
    • 별도의 이름 공간(스코프)를 제공함으로써 동일한 이름의 여러 함수나 변수들이 각 모듈마다 독립적으로 정의될 수 있다.
  • 별도 파일 내에 파이썬 코드를 저장할 때 (즉, 모듈을 코딩할 때) 한글 처리
    • 파일의 맨 위에 다음 코드를 넣어 준다.
      • # -*- coding:utf-8 -*-
  • 모듈은 하나의 독립된 이름 공간을 확보하면서 정의된다.

2-4 모듈이 지닌 이름들 알아보기

  • dir(모듈): 모듈이 지니고 있는 모든 이름들을 리스트로 반환
In [5]:
import string
print(dir(string))
['Formatter', 'Template', '_ChainMap', '_TemplateMetaclass', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_re', '_string', 'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', 'punctuation', 'whitespace']

2-5 이름 공간을 제공하는 다른 예들

  • 독립된 이름 공간(스코프)을 제공하는 것들
    • 모듈
    • 함수
    • 클래스
    • 객체
  • string 모듈 이름 공간에 변수 a를 생성한다.
    • 표준 모듈에 사용자가 정의하는 이름을 생성하는 것은 비추천
    • 단지 모듈 자체가 독립적인 이름 공간을 제공한다는 것을 알려줌
In [6]:
import string
string.a = 1
print(string.a)
1
  • 클래스도 독립적인 이름 공간
In [7]:
class C:            # 클래스도 독립적인 이름 공간
    a = 2           # 클래스 이름 공간 내에 변수 선언
    pass            # 클래스 정의 완료

c = C()             # 클래스 인스턴스 객체 생성
c.a = 1             # 클래스에서 생성된 인스턴스 객체도 별도의 이름 공간
print(c.a)
print(c.__class__.a)
print(C.a)
1
2
2
  • 함수도 독립적인 이름 공간
    • 다만 함수 내에서 선언된 지역(로컬) 변수는 함수 외부에서 접근할 수 없다.
In [9]:
x = 10    # 현재 모듈 내부에 정의되는 이름
def f():
    a = 1
    b = 2 # 현재 모듈에 정의되는 함수 f 내에 이름 a,b를 정의하고있다. 함수도 독립적인 이름 공간
f.c = 1
print(f.c)
print()
print(f.a)
1

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-4ccf5ee8b313> in <module>()
      6 print(f.c)
      7 print()
----> 8 print(f.a)

AttributeError: 'function' object has no attribute 'a'

3 모듈 검색 경로


3-1 PYTHONPATH 환경 변수 설정하기

  • 파이썬이 모듈을 찾는 순서

    • 1) 이미 메모리에 로딩되어진 것
    • 2) 현재 디렉토리 (ipython에서 pwd 명령으로 확인 가능)

      • ! pwd
  • 3) PYTHONPATH 환경 변수에 기술된 디렉토리 목록을 차례로 탐색
  • 4) 표준 라이브러리 디렉토리들
    • sys 모듈 임포트 후 sys.path 로 확인 가능
    • sys.path.append(), sys.path.remove()로 추가, 삭제 가능
    • PYTHONPATH 환경 변수 설정 방법
  • 윈도우즈
    • 제어판\시스템 및 보안\시스템\고급 시스템 설정\환경 변수
      • 새로 만들기: 변수 이름 - PYTHONPATH, 변수 값 - C:\Users\yhhan\mypythonlib
      • python 새로 시작하기 (cmd창 새로 시작한 후)
  • MAC이나 리눅스
    • ~/.bashrc, ~/.bash_profile, 혹은 ~/.profile 파일에 다음 라인 추가
      • export PYTHONPATH=/Users/yhhan/mypythonlib
      • 터미널 창에서 다음 명령어 수행
        • source ~/.bash_profile
  • 이클립스에서 PYTHONPATH 설정
  • [참고] https://goo.gl/crPFi0

inheritance

  • 코드 내에서 모듈 검색 경로 확인하기
In [13]:
import sys
print sys.path
['', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python27.zip', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python2.7', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python2.7/plat-darwin', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python2.7/plat-mac', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python2.7/plat-mac/lib-scriptpackages', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python2.7/lib-tk', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python2.7/lib-old', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python2.7/lib-dynload', '/Users/yhhan/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages', '/Applications/Canopy.app/appdata/canopy-1.4.1.1975.macosx-x86_64/Canopy.app/Contents/lib/python2.7/site-packages', '/Users/yhhan/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/IPython/extensions']

3-2 모듈의 검색 경로 동적으로 바꾸기

In [17]:
import sys

sys.path.append('~/mypythonlib')
print(sys.path)
['', '/Users/yhhan/anaconda/lib/python36.zip', '/Users/yhhan/anaconda/lib/python3.6', '/Users/yhhan/anaconda/lib/python3.6/lib-dynload', '/Users/yhhan/anaconda/lib/python3.6/site-packages', '/Users/yhhan/anaconda/lib/python3.6/site-packages/Sphinx-1.5.1-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/aeosa', '/Users/yhhan/anaconda/lib/python3.6/site-packages/pip-9.0.1-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/six-1.10.0-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/sim2net-3.1.2-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/setuptools-33.1.1-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/IPython/extensions', '/Users/yhhan/.ipython', '~/mypythonlib']
In [18]:
sys.path.insert(0, '~/mypythonlib2')
print(sys.path)
['~/mypythonlib2', '', '/Users/yhhan/anaconda/lib/python36.zip', '/Users/yhhan/anaconda/lib/python3.6', '/Users/yhhan/anaconda/lib/python3.6/lib-dynload', '/Users/yhhan/anaconda/lib/python3.6/site-packages', '/Users/yhhan/anaconda/lib/python3.6/site-packages/Sphinx-1.5.1-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/aeosa', '/Users/yhhan/anaconda/lib/python3.6/site-packages/pip-9.0.1-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/six-1.10.0-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/sim2net-3.1.2-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/setuptools-33.1.1-py3.6.egg', '/Users/yhhan/anaconda/lib/python3.6/site-packages/IPython/extensions', '/Users/yhhan/.ipython', '~/mypythonlib']

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일