패키지
파이썬은 프로그램을 좀 더 확장 가능하게 할 수 있도록 패키지(package)라는 파일 계층 구조를 구성할 수 있음
- 관련이 있는 모듈들을 묶어서 패기지로 제공하는 것이 가능
- 패키지는 __init__.py파일이 포함된 디렉터리
- 패키지 내에 다른 패키지가 포함되는 구조로도 구성이 가능
- 패키지도 모듈과 같은 방식으로 임포트
실습
- pycharm으로 프로젝트(프로젝트명: package-ex)를 생성
- Project 창에서 package-ex 디렉터리를 우클릭하여 [new] -> [python file] 선택 후 "main"을 입력하여 main.py파일 생성
- Project 창에서 package-ex 디렉터리를 우클릭하여 [new] -> [Directory] 선택 후 "game"을 입력하여 디렉터리 생성
- 생성된 game 디렉터리를 우클릭하여 [new] -> [python file] 선택 후 computer를 입력하여 파이썬 파일 생성
- 3번과 같은 과정으로 user.py와 play.py파일 생성
computer.py
from random import choice
def choose_computer():
return choice(['가위', '바위', '보'])
if __name__ == '__main__':
for _ in range(10):
print(choose_computer())
#for문에서 _ 언더바로 변수를 사용하는데 사용하지 않을 변수다 라는 의미로 사용한다.
user.py
def choose_user():
error_message = '잘못된 입력입니다. 1~3사이의 숫자로 입력해주세요 \n'
choices = ['가위','바위','보']
while True:
for i, v in enumerate(choices):
print(i+1,v)
try:
index = int(input('선택 > ')) -1
if 0 <=index <len(choices):
return choices[index]
print(error_message)
except:
print(error_message)
#continue
if __name__ == '__main__':
result = choose_user()
print(result)
play.py
count = {'win':0,'lose':0,'draw':0}
def run(p1,p2):
if p1 == p2:
result = 'draw'
elif p1 == '가위':
result = 'win' if p2 == '보' else 'lose'
elif p1 == '바위':
result = 'win' if p2 == '가위' else 'lose'
else:
result = 'win' if p2 == '바위' else 'lose'
count[result] += 1
return result
def print_result():
print('Result' .center(40, '#'))
print('Win',count['win'], 'lose',count['lose'],'Draw',count['draw'])
print('#' *40)
if __name__ == '__main__':
print(run('가위','보'))
print(run('가위', '바위'))
print(run('가위', '가위'))
print(run('보', '가위'))
print(run('보', '가위'))
print_result()
#<값1> if <조건> else <값2> 구문: <조건>이 참일 때는 <값1>이 아니면 <값2>가 결과가 됨
main.py
from game import user, computer, play
while True:
you = user.choose_user()
com = computer.choose_computer()
result = play.run(you, com)
print('You:', you, 'Computer:', com, 'result', result)
answer = input('게임을 더 하시겠습니까?y/n').lower()
if answer.startswith('n'): #맨앞의 글자가 n이면 조건문 실행
break
play.print_result()
결과
1 가위
2 바위
3 보
선택 > 2
You: 바위 Computer: 가위 result win
게임을 더 하시겠습니까?y/nn
#################Result#################
Win 1 lose 0 Draw 0
########################################
만약 다음과 같이 모듈을 import하게 된다면 오류가 발생한다.
import game
while True:
you = game.user.choose_user()
com = game.computer.choose_computer()
result = game.play.run(you, com)
print('You:', you, 'Computer:', com, 'result', result)
answer = input('게임을 더 하시겠습니까?y/n').lower()
if answer.startswith('n'):
break
game.play.print_result()
패키지는 from이라는 구문으로 가지고 온 후 모듈들을 각각 import를 수행해야한다.
(패키지만 가지고와서 사용하면 안된다. 최종적으로 import가 되려면 모듈이 import가 되어야한다)
아래와 같은 방법으로 호출하여 사용할 수 있다.
from game.user import choose_user
import game.computer
import game.play
while True:
you = choose_user()
com = game.computer.choose_computer()
result = game.play.run(you, com)
print('You:', you, 'Computer:', com, 'result', result)
answer = input('게임을 더 하시겠습니까?y/n').lower()
if answer.startswith('n'):
break
game.play.print_result()
__init.py__
해당 디렉터리가 패키지임을 알려주는 파일
>>> 앞의 실습에서 game 디렉터리에 __init__.py가 없어도 패키지가 인식이 되었지만, 해당 디렉터리를 패키지로 만들기 위해서는 __init__.py파일을 추가하는 것을 권장
__init__.py파일의 __all__변수
- main.py파일의 from game import user, computer, play를 from game import * 으로 바꾸게 되면 오류 발생
- game 디렉터리에 __init__.py 파일을 생성하고 다음과 같이 내용을 추가하면 오류가 사라짐
- __all__=['computer','play','user']
- __all__변수는 import * 을 할 때 임포트 되는 모듈들을 나열하는 변수
만약 위의 main.py의 import구문을 다음과 같이 변경하였으면 불러와야 하는데 불러오지를 못한다.
from game import *
while True:
you = user.choose_user()
com = computer.choose_computer()
result = play.run(you, com)
print('You:', you, 'Computer:', com, 'result', result)
answer = input('게임을 더 하시겠습니까?y/n').lower()
if answer.startswith('n'): #맨앞의 글자가 n이면 조건문 실행
break
play.print_result()
결과
Traceback (most recent call last):
File "C:\main.py", line 3, in <module>
you = user.choose_user()
NameError: name 'user' is not defined
그 이유는 __init__.py파일이 없기 때문이다
(파이썬 3.3이후 부터 init파일이 없어도 패키지 동작 수행이 가능하지만 위와같이 game 디렉토리 안에 모든 모듈들을 호출 및 사용하고 싶을 때 해당 패키지안에 init.py파일을 생성해 주어야한다)
__init__.py
__all__ = ['computer', 'play', 'user']
docstring
- 파이썬은 함수뿐만 아니라 모듈, 패키지에도 docstring을 작성할 수 있다.
- 모듈의 docstring
- 파일의 최상단(첫 번째 라인부터 시작)에 작성된 문자열
- 패키지의 docstring
- __init__.py파일의 최상단(첫 번째 라인부터 시작)에 작성된 문자열
모듈 파일에 docstring을 추가할 수 있는데
예를들어 play.py파일 최상단에 다음과 같은 문장을 추가하자
'''Dostring of play module'''
count = {'win':0,'lose':0,'draw':0}
def run(p1,p2):
if p1 == p2:
result = 'draw'
...이하생략
main.py에서 다음 명령문을 통해 실행하면
from game import *
# while True:
# you = user.choose_user()
# com = computer.choose_computer()
# result = play.run(you, com)
# print('You:', you, 'Computer:', com, 'result', result)
# answer = input('게임을 더 하시겠습니까?y/n').lower()
# if answer.startswith('n'):
# break
#
# play.print_result()
help(play)
결과
Help on module game.play in game:
NAME
game.play - Dostring of play module
FUNCTIONS
print_result()
run(p1, p2)
DATA
count = {'draw': 0, 'lose': 0, 'win': 0}
FILE
c:\package-ex\game\play.py
다음과 같이 출력되며, docstring만 출력하고 싶으면 해당 아래와 같은 명령문을 사용하면된다.
print(play.__doc__)
결과
Dostring of play module
패키지도 마찬가지로 docstring을 추가할 수 있다.
__init__.py파일에
'''Packaging Docstring'''
main.py파일을 실행시키면
import game
print(game.__doc__)
결과
Packaging Docstring
Problems
다음과 같이 패키지가 구성되어 있을 때, from graphic import * 구문과 from graphic.image import *구문을 실행할 때 각 패키지 내의 모든 모듈 또는 패키지가 로딩이 되려면 어떻게 해야 하는가?
>>> graphic 디렉터리 내의 __init__.py파일에 __all__=['display','image']코드 작성
>>> image 디렉터리 내의 __init__.py파일에 __all__=['gif','jpeg','png']코드 작성
위와 같이 패키지가 구성되어 있을 때, gif 모듈에서 display 모듈을 임포트하는 구문을 작성하시오
>>> from graphic import display
위와 같이 패키지가 구성되어 있을때 ,gif 모듈에서 display 모듈에 있는 모든 속성을 임포트하는 구문을 작성하시오
>>> from graphic.display import *
Summary
- 패키지란 여러 모듈들이 담긴 디렉터리를 말한다
- 패키지는 파일들을 계층적인 구조로 관리하도록 하여 관련성 있는 모듈들을 묶어주는 기능을 한다
- 패키지는 __init__.py파일을 포함하는 디렉터리이다.
- __init__.py파일의 __all__변수는 import * 구문을 수행 할 때 로딩이 되는 모듈들을 나열한 리스트 변수이다.
- 파이썬은 모듈과 패키지도 docstring을 제공하여 모듈과 패키지의 사용을 더 쉽게 한다.
'Language > Python' 카테고리의 다른 글
[Python] Ch7 - part1. 클래스 (0) | 2021.07.01 |
---|---|
[Python] Ch6 - part 3. 라이브러리 (0) | 2021.06.29 |
[Python] Ch6 - part1. 모듈 (0) | 2021.04.24 |
[Python] Ch5 - 함수 (0) | 2021.04.24 |
[Python] Ch4 - part 3. 컴프리헨션 (0) | 2021.04.07 |