TIL Python Chapter 52 How Import Statement Finds Modules & Packages (과제1,2)

finelinefe·2020년 8월 24일
0

PYTHON

목록 보기
1/6
post-thumbnail

1. sys.modules과 sys.path 차이점

sys.modules = 패키지를 찾기 위해 가장 먼저 확인되는(하는) 곳. 단순 딕셔너리 형태. 이미 불러온 모듈+패키지 가지고 있으며 새로 import 하는 모듈은 여기서 찾을 수 있음.

sys.path = 패키지를 찾기 위해 가장 나중에 확인되는(하는) 곳. list 형태. string 가지고 있음.

sys.path

['',
 '/Users/song-eun-u/anaconda3/bin',
 '/Users/song-eun-u/anaconda3/lib/python36.zip',
 '/Users/song-eun-u/anaconda3/lib/python3.6',
 '/Users/song-eun-u/anaconda3/lib/python3.6/lib-dynload',
 '/Users/song-eun-u/anaconda3/lib/python3.6/site-packages',
 '/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/aeosa',
 '/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/IPython/extensions',
 '/Users/song-eun-u/.ipython']

sys는 파이썬에서 제공하는 모듈이기 때문에 수정과 출력 둘 다 가능

import sys

print(sys.path)
print(sys.modules)

또한 파이썬에서 불러오고자 하는 모듈+패키지를 찾을때의 순서는 아래와 같다

sys.modules > built-in > sys.path / 없다면 ModuleNotFoundError


2. 파이썬이 sys module의 위치를 찾는 것

sys 모듈은 파이썬에 기본 내장된 모듈이다. 따라서 자동적으로 위치를 알고있다.


3. 절대경로와 상대경로의 차이점

절대경로(absolute path) = 어떤 파일이나 경로에 대해 절대적인 경로만을 가진다. 최상위 디렉토리에서 시작한다. top-bottom 식으로 내려간다. 일반적으로 가장 많이 사용된다

상대경로(relative path) = 절대경로와 다르게 불러오고자 하는 위치를 기준으로 경로를 정의하기 때문에 각각 다르다. 때문에 다른 로컬 to 로컬 식으로 import 할 때 사용된다. 상위 모듈 이동시 .. 를 사용. 그러나 파일 위치 변경마다 경로가 바뀌니 가급적 적게 사용하는 것이 바람직하다


4. calculator 패키지 만들기

앞으로 개발하면서 많은 패키지를 사용할 것이고 만들어야 하는 경우도 있을 수 있기 때문에 이번과제는 직접 패키지를 만들어 보는 과제 입니다.

로컬 환경에서 파이썬을 설치하고 진행해 주세요.

디렉토리 구조는 다음과 같고 각 파일의 코드내용은 다음과 같습니다.
init.py 파일에는 아무코드도 없지만 init 파일은 해당 디렉토리가 패키지임을 알려주는 역할을 합니다.

<main.py>

# absoulte path
#from calculator.add_and_multiply import add_and_multiply 

# relative path
from .calculator.add_and_multiply import add_and_multiply

if __name__ == '__main__':
    print(add_and_multiply(1,2))


<add_and_multiply.py>

from .multiplication import multiply
# from calculator.multiplication import multiply
def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)



<multipliation.py>

def multiply(a,b):
    return(a*b)



패키지 구조


5. main.py에서 상대경로로 add_and_multiply import 시 발생하는 에러 확인 후 파이썬 공식 문서를 참고해서 main module에서는 패키지의 모듈을 어떻게 임포트 해야하는지 알아보시오.

상대경로로 import 한 결과 ImportError가 뜨는데 이는 상위(부모)패키지가 없어서 생긴 것이다. 그러므로 이는 상대경로가 아니라 절대경로로 import 해야 한다.
절대경로로 import 한 결과 정상적으로 import 됐고 실행결과는 5가 반환된다. 또한 if name == 'main': 구문의 경우 모듈의 이름을 name으로 바꾸는 과정에서 최상위 위치로 바꿔버리기 때문에 상대경로로 불러오지 못한 오류가 난 것이다.


6. add_and_multiply.py에서 multiply 함수를 절대경로와 상대경로로 각각 import 하고 main 모듈과 차이점을 생각해보고 결과를 출력하시오.

절대경로 import 결과 실행된다

상대경로 import 결과 importerror : attempted relative import with no known parent package 라는 오류가 뜬다. 이는 메인 모듈과 다르게 calaulator 패키지 내의 모듈이 add_and_multiply 라는 것을 의미한다. 또한 메인 모듈은 이 모듈의 함수를 받는 위치라는 것을 알려주는 것 같다.


7. init.py 파일의 역할

init.py는 패키지를 가져올 때 초기화를 도와준다. 주로 패키지 안에 파일이 있을 경우 해당 패키지를 import 할 때 자동으로 실행된다. 하는 역할은 다음과 같다

  1. import 할 때 경로의 총 길이 주기
# __init__.py
.mod1에서 가져 오기 

--> 매번 모든 경로를 타입해야하는 번거로움을 없애기 위해
__init__.py 파일을 통해 서 경로를 찾을 수 있고 이것을 import 해주면 된다

# main.py
pkg import func2에서

func2 ()
  1. package에서 import 할 수 있는 변수, 함수, 클레스 제한
package를 통해 불러올 수 있는 요소는 __all__변수로 정의된다. 
이는 (1)모든함수/(2)함수/(3)클래스이다. 이에 한해서 제한 가능하다.
__all__ 변수는 문자열 값의 요소를 가진다. 때문에 string 형으로 리스트에 선언한다.

<br />
# __init__.py
.mod1에서 가져 오기 func2
.mod2에서 가져 오기 func3

__all__ = [ 'func2', 'func3']


# main.py
pkg 가져 오기에서 *

func2 ()
func3 ()
func4 () ## <== 오류. func4 함수는 __all__에 정의되지 않음...


그 외
3) package가 import 될 때 먼저 실행되어야 할 코드 가 있다.

0개의 댓글