패키지
관련있는 모듈들의 집합을 의미
패키지는 도트(.)을 사용하여 파이썬 모듈을 계층적(디렉터리 구조)으로 관리할 수 있게해줌
A.B 라는 모듈 이름의 경우 A가 패키지이름, B가 모듈이름을 의미
smartphone/
__init__.py
camera/
__init__.py
shutter.py
gallery.py
call/
__init__.py
contact.py
message.py
time/
__init__.py
stopwatch.py
alarm.py
위처럼 smartphone, camera, call, time은 디렉토리를 의미
확장자가 .py인 파일은 모듈을 의미
패키지 구조로 파이썬 프로그램을 만드는것이 공동 작업이나 유지보수 측면에서
확장자가 .py인 파일은 모듈을 의미

함수명은 각파일명_test로 설정
함수가 실행되면 각 모듈명이 출력됨



set PYTHONPATH=C:\~형식으로 패키지의 상위디렉토리의 절대 경로값을 넣어주면됨
python 명령어로 인터프리터를 실행 시킬 수 있음


from.. import하여 실행 시키는 방법

위 코드처럼 import smartphone를 하고 사용하면 오류가 발생
import smartphone를 수행하면 smartphone 디렉터리의 모듈 또는 smartphone 디렉토리의 __init__ py에 정의한것만 사용할 수 있음

위처럼 임포트 하는것도 사용할 수 없음 import문에서 맨마지막은 항상 패키지여야 하기떄문
위 코드는 함수를 임포트해서 오류가 발생함
__init__.py의 용도__init__.py는 해당 디렉토리가 패키지의 일부임을 알려주는 역할
디렉토리속에 __init__.py가 없다면 패키지로 인식이 되지 않음

__init__.py를 설정해주지 않아서 오류가 발생함
위와 같이 특정 디렉토리의 모듈을 *을 사용하여 임포트 할때는 __init__.py를 설정해주어야됨


__init__.py에 __all__ 을 작성하고 아래 이미지와 같이 임포트하니가 정상 작동되는것을 확인할 수 있음# message.py
from smartphone.camera.gallery import gallery_test
def message_test():
print("message")
gallery_test()

인터프리터에서 위와같이 확인할 수 있음
위 경우 전체경로를 사용해 import하는 경우
# message.py
from ..camera.gallery import gallery_test
def message_test():
print("message")
gallery_test()
import문이 from smartphone.camera.gallery import gallery_test에서 from ..camera.gallery import gallery_test로 변경되었음
..은 부모디렉토리를 의미함
..와 같은 relative한 접근자는 모듈안에서만 사용이 가능함
예외 처리
오류를 무시하고 싶을때 예외 처리를 사용
파이썬은 try, exception을 사용해서 오류를 처리할 수 있게 해줌

FileNotFoundError이 발생
ZeroDivisionError이 발생
IndexError이 발생try:
...
except [발생 오류[as 메시지 변수]]:
...
try, except문의 기본 구조
try 블록 수행중 오류가 발생하면 except블록이 수행됨
but, try 블록에서 오류가 발생하지 않는다면 except문도 수행안됨
except 구문은 except [발생 오류[as 메시지 변수]]: 형식으로 사용되는데 []기호는 괄호 안의 내용을 생략할 수 있다는 관례 표기법
try:
...
except:
...
try:
...
except 발생 오류:
...
try:
...
except 발생 오류 as 오류 메시지 변수:
...
try문에는 finally 절을 사용할 수 있음
finally절은 try문 수행 도중 예외 발생 여부 상관없이 항상 수행됨
보통 finally절은 사용한 리소스를 close해야 할 때에 많이 사용
try:
...
except 발생 오류 1:
...
except 발생 오류2:
...
try:
a = [1,2]
print(a[3])
4/0
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")
except IndexError:
print("인덱싱 할 수 없습니다.")

try:
f = open('unexist.txt', 'r')
except FileNotFoundError:
pass
오류를 일부로 발생시켜야 하는 경우도 있음
파이썬은 raise명령어를 사용해 오류를 강제로 발생시킬 수 있음
예를들어 Bird 클래스를 상속받은 자식 클래스는 반드시 fly라는 함수를 구현하도록 만들고 싶은 경우가 있다
class Bird:
def fly(self):
raise NotImplementedError
class Eagle(Bird):
pass
eagle = Eagle()
eagle.fly

자식 클래스가 fly함수를 구현하지 않고 fly함수를 호출하면 fly함수가 구현되지 않았기 때문에 NotImplementedError이 발생
오류가 뜨지 않게하려면 Eagle클래스에서 fly함수를 구현하면됨
class Myerror(Exception):
pass
def say_nick(nick):
if nick == '바보':
raise Myerror()
print(nick)
say_nick('천사')
say_nick('바보')

예외를 만들기 위해서는 파이썬의 내장 클래스인 Exception을 상속 받으면됨
예외이기떄문에 try exception에도 사용가능함
class Myerror(Exception):
pass
def say_nick(nick):
if nick == '바보':
raise Myerror()
print(nick)
try:
say_nick('천사')
say_nick('바보')
except Myerror:
print("허용되지 않는 별명입니다.")

class Myerror(Exception):
def __str__(self):
return '허용되지 않는 별명입니다.'
def say_nick(nick):
if nick == '바보':
raise Myerror()
print(nick)
try:
say_nick('천사')
say_nick('바보')
except Myerror as e:
print(e)

__str__ 메서드를 구현해야함