파이썬 모듈: 코드 구성으로 명확성과 재사용성 높이기
모듈을 사용하면 파이썬 코드를 논리적으로 구성할 수 있습니다. 관련 코드를 모듈로 그룹화하면 코드를 더 쉽게 이해하고 사용할 수 있습니다. 모듈은 임의의 이름을 가진 속성을 바인딩하고 참조할 수 있는 파이썬 객체입니다.
간단히 말해, 모듈은 파이썬 코드로 구성된 파일입니다. 모듈은 함수, 클래스, 변수를 정의할 수 있으며, 실행 가능한 코드도 포함할 수 있습니다.
예제
aname이라는 모듈의 파이썬 코드는 일반적으로 aname.py라는 파일에 저장됩니다. 다음은 support.py라는 간단한 모듈 예제입니다.
def print_func(par):
print("Hello : ", par)
return
import 문
다른 파이썬 소스 파일에서 import 문을 실행하여 모든 파이썬 소스 파일을 모듈로 사용할 수 있습니다. import 문의 구문은 다음과 같습니다.
import module1[, module2[,... moduleN]
인터프리터가 import 문을 만나면 검색 경로에 모듈이 있는 경우 해당 모듈을 가져옵니다. 검색 경로는 인터프리터가 모듈을 가져오기 전에 검색하는 디렉터리 목록입니다. 예를 들어, support.py 모듈을 가져오려면 스크립트 상단에 다음 명령을 추가해야 합니다.
#!/usr/bin/python
# support 모듈 가져오기
import support
# 이제 모듈에서 정의된 함수를 다음과 같이 호출할 수 있습니다.
support.print_func("Zara")
위 코드를 실행하면 다음과 같은 결과가 나옵니다.
Hello : Zara
모듈은 임포트 횟수에 관계없이 한 번만 로드됩니다. 따라서 여러 번 임포트하더라도 모듈 실행이 반복되지 않습니다.
from...import 문
파이썬의 from 문을 사용하면 모듈에서 특정 속성을 현재 네임스페이스로 가져올 수 있습니다. from...import 구문은 다음과 같습니다.
from modname import name1[, name2[, ... nameN]]
예를 들어, fib 모듈에서 fibonacci 함수를 가져오려면 다음 문을 사용합니다.
from fib import fibonacci
이 문은 fib 모듈 전체를 현재 네임스페이스로 가져오지 않으며, fib 모듈에서 fibonacci 항목만 임포트하는 모듈의 전역 심볼 테이블에 도입합니다.
from...import * 문
다음 import 문을 사용하여 모듈의 모든 이름을 현재 네임스페이스로 가져올 수도 있습니다.
from modname import *
이 방법은 모듈의 모든 항목을 현재 네임스페이스로 쉽게 가져올 수 있지만, 이 문은 신중하게 사용해야 합니다.
모듈 찾기
모듈을 임포트할 때 파이썬 인터프리터는 다음 순서로 모듈을 검색합니다.
모듈 검색 경로는 시스템 모듈 sys의 sys.path 변수에 저장됩니다. sys.path 변수에는 현재 디렉터리, PYTHONPATH, 설치 종속 기본 경로가 포함됩니다.
PYTHONPATH 변수
PYTHONPATH는 디렉터리 목록으로 구성된 환경 변수입니다. PYTHONPATH의 구문은 셸 변수 PATH와 동일합니다.
다음은 Windows 시스템의 일반적인 PYTHONPATH 예입니다.
set PYTHONPATH = c:\python20\lib;
다음은 UNIX 시스템의 일반적인 PYTHONPATH 예입니다.
set PYTHONPATH = /usr/local/lib/python
네임스페이스와 스코핑
변수는 객체에 매핑되는 이름(식별자)입니다. 네임스페이스는 변수 이름(키)과 해당 객체(값)의 딕셔너리입니다.
파이썬 문은 로컬 네임스페이스와 전역 네임스페이스의 변수에 접근할 수 있습니다. 로컬 변수와 전역 변수의 이름이 같으면 로컬 변수가 전역 변수를 가립니다.
각 함수에는 고유한 로컬 네임스페이스가 있습니다. 클래스 메서드는 일반 함수와 동일한 스코핑 규칙을 따릅니다.
파이썬은 변수가 로컬인지 전역인지 추측합니다. 함수에서 변수에 값이 할당되면 파이썬은 해당 변수를 로컬로 간주합니다.
따라서 함수 내에서 전역 변수에 값을 할당하려면 먼저 global 문을 사용해야 합니다.
global VarName 문은 파이썬에게 VarName이 전역 변수임을 알립니다. 파이썬은 해당 변수에 대해 로컬 네임스페이스 검색을 중단합니다.
예를 들어, 전역 네임스페이스에 Money 변수를 정의합니다. Money 함수 내에서 Money에 값을 할당하면 파이썬은 Money를 로컬 변수로 간주합니다. 그러나 로컬 변수 Money의 값에 접근하기 전에 설정하지 않았으므로 UnboundLocalError가 발생합니다. global 문의 주석을 해제하면 문제가 해결됩니다.
#!/usr/bin/python
Money = 2000
def AddMoney():
# 다음 줄의 주석을 해제하여 코드 수정:
# global Money
Money = Money + 1
print(Money)
AddMoney()
print(Money)
dir() 함수
내장 함수 dir()은 모듈에서 정의된 이름을 포함하는 정렬된 문자열 목록을 반환합니다.
이 목록에는 모듈에서 정의된 모든 모듈, 변수, 함수의 이름이 포함됩니다. 다음은 간단한 예제입니다.
#!/usr/bin/python
# 내장 모듈 math 임포트
import math
content = dir(math)
print(content)
위 코드를 실행하면 다음과 같은 결과가 나옵니다.
['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
여기서 특수 문자열 변수 __name__은 모듈의 이름이고, __file__은 모듈이 로드된 파일 이름입니다.
globals()와 locals() 함수
globals()와 locals() 함수는 호출 위치에 따라 전역 및 로컬 네임스페이스의 이름을 반환하는 데 사용할 수 있습니다.
locals()가 함수 내부에서 호출되면 해당 함수에서 로컬로 접근할 수 있는 모든 이름을 반환합니다.
globals()가 함수 내부에서 호출되면 해당 함수에서 전역적으로 접근할 수 있는 모든 이름을 반환합니다.
두 함수의 반환 타입은 딕셔너리입니다. 따라서 keys() 함수를 사용하여 이름을 추출할 수 있습니다.
reload() 함수
모듈이 스크립트로 임포트되면 모듈의 최상위 부분 코드는 한 번만 실행됩니다.
따라서 모듈의 최상위 코드를 다시 실행하려면 reload() 함수를 사용할 수 있습니다. reload() 함수는 이전에 임포트한 모듈을 다시 임포트합니다. reload() 함수의 구문은 다음과 같습니다.
reload(module_name)
여기서 module_name은 다시 로드하려는 모듈의 이름이지, 모듈 이름을 포함하는 문자열이 아닙니다. 예를 들어, hello 모듈을 다시 로드하려면 다음과 같이 합니다.
reload(hello)
파이썬 패키지
패키지는 단일 파이썬 애플리케이션 환경을 정의하는 계층적 파일 디렉터리 구조로, 모듈과 서브패키지, 서브-서브패키지 등으로 구성됩니다.
Phone 디렉터리에 Pots.py 파일이 있다고 가정해 보겠습니다. 이 파일에는 다음 소스 코드 줄이 있습니다.
#!/usr/bin/python
def Pots():
print("I'm Pots Phone")
마찬가지로, 위와 같은 이름을 가진 다른 함수를 가진 두 개의 파일이 더 있습니다.
이제 Phone 디렉터리에 __init__.py 파일을 하나 더 만듭니다.
Phone을 임포트할 때 모든 함수를 사용하려면 __init__.py에 명시적 import 문을 넣어야 합니다.
from Pots import Pots
from Isdn import Isdn
from G3 import G3
이 줄을 __init__.py에 추가한 후 Phone 패키지를 임포트하면 모든 클래스를 사용할 수 있습니다.
#!/usr/bin/python
# 이제 Phone 패키지 임포트
import Phone
Phone.Pots()
Phone.Isdn()
Phone.G3()
위 코드를 실행하면 다음과 같은 결과가 나옵니다.
I'm Pots Phone
I'm 3G Phone
I'm ISDN Phone
위 예제에서는 각 파일에 단일 함수를 예로 들었지만, 파일에 여러 함수를 유지할 수 있습니다. 또한 해당 파일에 다양한 파이썬 클래스를 정의한 다음 해당 클래스에서 패키지를 생성할 수도 있습니다.