python, about import modules & packages

yo·2020년 5월 30일
0

주절주절

-decorator는 파이썬 학습을 좌절시키기 위한 단 하나의 목적으로 파이썬개발자에 의해 체계적으로 고안된 것임이 분명하다.
-그에 비하면 modules, packages는 아주 감사한 기능이다.
-이 기능들로 인해 남이 만들어 놓은 것을 쉽게 가져다가 쓸 수 있다.
-relative path는 decorator 만큼은 아니지만 이해하고 활용하기 꽤나 까다롭다.

1. sys.modules와 sys.path의 차이점.

-파이썬은 sys.modules->built-in modules->sys.path 순서대로 모듈의 장소를 찾는다.
-sys.modules는 이미 import된 모듈과 package들을 저장하고 있고 dictionary 형태로 되어있다. 그 말인즉슨, 처음 불러오는 모듈, 패키지는 여기서 못 찾는다.
sys.path는 파이썬이 앞의 두 곳에서 찾지 못하였을 때 마지막으로 오는 곳이다.
pip로 설치한 외부 모듈가 자동으로 site-packages라는 디렉토리에 설치되는데, 이 site-packages는 sys.path에 이미 포함되어 있다. (참고로 sys.path는 리스트로 되어있다)

2. sys도 import해야 하는 모듈인데, 어떻게 python이 sys의 위치를 찾는 것인가?

모듈과 패키지를 찾아내는 sys도 그 자신이 모듈이다.
요 sys에 대해 알아보자

import sys
print(sys)

해서 sys 를 부르면 아래의 결과를 얻는다.

<module 'sys' (built-in)>

아하, sys는 빌트인 모듈이다. 당연히 python이 간단하게 찾을 수 있다.

3.Differences between absolute path and relative path

모듈, 패키지 찾아갈 때 두 가지 경로가 있다. 절대경로, 상대경로.

절대경로

는 말 그대로절대적(변하지 않는) 주소를 같는다.
내가 맞게 이해했다면, 일상생활에서 쓰는 주소와 같다.
서울시 강남구 테헤란로 427
전국 8도에서 시로, 시에서 구로, 구에서 읍.면.동으로 좁혀가며 주소를 적는다.
이게 절대경로다.

module5를 임포트 하려면 아래처럼 하면 된다.
package2.subpackage1.module5 import function2
.은 다음단계로 가는 뜻이다.
제일 상위주소인 my app은 안적는게 원칙이다. 우리나라에서 주소 적을 때 '대한민국'부터 적는 사람이 없듯이, 당연해서 안적는다.

상대경로

는 import하는 위치를 기준으로 경로를 정한다. 일반적으로 local package 안에서 다른 local package를 import할 때 사용한다. '우리 집 옆 건물' 같은 느낌이라고 할까?
그래서 좀 위험하다. 우리 집이 이사가면 우리집 옆 건물이 뜻하는 바가 달라진다.
우리 집 옆건물과 우리집 사이에 새로운 집에 지어져도 마찬가지다.
웬만하면 absolute path를 사용하자.

package2의 module3에서 package2의 class1과 package2의 하위 package인 subpackage1의 module5의 function2 함수를 import하려고 하면 아래와 같이 할 수 있다.

#package2/module3.py
from .import class1
from .subpackage1.module5 import function2

dot(.)은 import가 선언되는 파일의 현재 위치를 의미한다. 현재위치는 package2/module3.py이므로 현재 위치에서부터 원하는 모듈의 경로만 선언해주면 된다.
dot 2개(..)는 현재위치에서 상위 디렉토리로 가는 경로다.

#subpackage1/module5.py
from ..module4 import class4

4.Calculator package 만들기


과제에서 주어진대로 모듈을 만들고 main.py를 실행했더니 아래와 같은 문제가 발생했다.

5. main.py에서 상대경로로 add_and_multipy를 임포트 했을 때 발생하는 에러를 확인하고, main module에서는 패키지의 모듈을 어떻게 임포트 해야하는지 블로깅하기.

위의 오류는 main.py가 최상위 파일이라 발생하는 오류다.
main.py에서 나머지를 주석처리하고 print(__name__) 을 실행하면 __main__값이 출력된다.
이럴 땐 패키지를 절대경로를 통해 import해야한다.

# absoulte path
from calculator.add_and_multiply import add_and_multiply 

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

위처럼 바꿔주면 결과가 잘 출력된다.

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

andd_and_multiply.py를 실행하면 아래같은 오류가 뜬다.

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


main.py에서 상대경로를 통해 호출했을 때와 같은 문제가 발생한다.
이 파일 역시 자기 입장에선 최상위 파일이기 떄문에 즉, __main__ 이기에 이런 문제가 발생한다. __main__인 애들은 무조건 절대경로로 모듈을 불러와야한다.
직접 실행되는 파일이 main이 된다. main.py실행시 add_and_multiply가 multiply를 상대참조 할 수 있었던 이유다. 하지만 add_and_multiply를 실행한다면 그게 직접 실행된 는 것이기 때문에 main이 된다. 해서 이 땐 상대경로로 하면 안되고 절대경로로 바꿔줘야 한다.

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

이렇게 절대경로로 바꿔주면 잘 작동된다.

참고로 처음엔 from calculator.multiplication import multiply
이렇게 했더니 안됐다. 뭐가 문젠가 봤더니 모듈 불러오는 쪽과 받는 쪽이 calculator라는 폴더 안에 같이 들어있었기 때문에, 그건 뺴고 그 뒤부터 적어야 했었다.
다음부턴 이런 실수 하지말자.

__init__.py 파일의 역할에 대해 정리하기

1. __init__.py는 자기가 속해있는 디렉토리가 패키지 임을 알려준다.

이게 없으면 파이썬이 그 디렉토디를 패키지로 인식하지 않는다.
python3.3부턴 이게 없어도 패키지로 인식된다.
하지만 하위버전과의 호환을 위해 적어주기로 한다.
존재 자체로 의미가 있기에 내용은 텅텅 비어도 된다. 하지만 내용을 채워서 몇가지 유용한 역할을 할 수 있다.

2. import경로를 줄여준다.

import할 내용을 __init__.py에 먼저 import해놓으면 경로가 짧아진다.
아래 예시를 찬찬히 읽어보면 이해가 될 것이다.

위에껀 __init__에 아무것도 쓰지 않은 것이다.
아래 예시는 __init__에 미리 add_and_multiply를 import한거다.

3. __all__활용

*를 써서 import할 땐, __init____all__ 안에 있는 내용만 import된다.
이래 내용을 참조하자.

profile
Never stop asking why

0개의 댓글