[Pre-course] 2021. 10. 11-2

GYUBIN ·2021년 10월 12일
0

Python


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

Import Search 순서:

 1. sys.modules
 2. built-in modules
 3. sys.path

sys.modules: 파이썬이 모듈이나 package를 찾기위해 가장 먼저 확인하는 곳
                 sys.modules는 단순한 dictionary이다
                 이미 import된 모듈과 package들을 저장하고 있다

built-in modules: 파이썬에서 제공하는 파이썬 공식 라이브러리들
                      이미 파이썬에 포함되어 나오므로 파이썬이 쉽게 찾을 수 있다

sys.path: 모듈이나 package를 찾기위해 마지막으로 보는 장소
            sys.path는 기본적으로 list이며 string 요소들을 가지고 있는 list
            각 string 요소들은 경로를 나타낸다
            sys.path 에서도 못찾으면 ModuleNotFoundError 에러를 리턴한다


  1. sys
import sys
print(sys)
# <module 'sys' (built-in)>

sys 모듈: built-in modules ( 파이썬에 포함되어 있는 모듈 )


  1. Absolute path와 relative path의 차이점

직접 개발한 local packageimport 할때는 해당 package의 위치에 맞게 import 경로를 선언해야 한다

└── my_app
    ├── main.py
    ├── package1
    │   ├── module1.py
    │   └── module2.py
    └── package2
        ├── __init__.py
        ├── module3.py
        ├── module4.py
        └── subpackage1
            └── module5.py

 Absolute path: import를 하는 파일이나 경로에 상관없이 항상 경로가 동일 ( 프로젝트의 최상단 디렉토리를 기준 )
 relative path: local package 안에서 다른 local packageimport 할때 사용 ( import 하는 위치를 기준 )

module5.py의 위치를 절대경로로 표시 : my_app/package2/subpackage1/module5.py(리눅스)
module4.py의 위치를 절대경로로 표시 : my_app/package2/module4.py(리눅스)

module5.py의 위치에서 module4.py의 위치를 상대경로로 표시 : ../module4.py(리눅스)


  1. main.py에서 상대경로로 add_and_mutiply 를 임포트 했을 때

에러 ImportError: attempted relative import with no known parent package 발생

이유는 무엇일까?
docs.python 을 참고하면 상대 임포트가 현재 모듈의 이름에 기반을 둔다는 것에 주의해야한다
메인 모듈의 이름은 항상 "__main__" 이기 때문에, 파이썬 응용 프로그램의 메인 모듈로 사용될 목적의 모듈들은 반드시 절대 임포트를 사용해야 한다는 것이다

좀 더 설명을 해보면 메인 모듈은 항상 최상단에 위치해있기 때문에 상대경로를 사용 시 no known parent package 알려진 상위 패키지가 없다고 뜨는 것이다

해결 방법은 절대경로를 사용하면 깔끔하게 해결 된다 !


  1. add_and_multiply.py에서 multiply함수를 절대경로와 상대경로로 각각 임포트하면?

multiply함수를 상대경로로 임포트

from .multiplication import multiply
#from calculator.multiplication import multiply
def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)
# absoulte path
from calculator.add_and_multiply import add_and_multiply , multiply
if __name__ == '__main__':
    print(add_and_multiply(1,2))
    print(multiply(1,2))
# 5
# 2


multiply함수를 절대경로로 임포트

#from .multiplication import multiply
from calculator.multiplication import multiply
def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)
# absoulte path
from calculator.add_and_multiply import add_and_multiply , multiply
if __name__ == '__main__':
    print(add_and_multiply(1,2))
    print(multiply(1,2))
# 5
# 2

두 방법 모두 main.py에서 출력이 잘 되는 것을 확인 할 수 있다

메인모듈과 차이가 나는 이유는 add_and_multiply.py 는 패키지 안에 들어있는 모듈이기 때문이다


  1. __init__.py 파일의 역할

__init__.py 는 해당 디렉토리가 패키지의 일부임을 알려준다

디렉토리의 모든 모듈을 불러 오고 싶을때 * 을 사용하면 오류가 발생한다

from calculator import *
if __name__ == '__main__':
    print(add_and_multiply(1,2))
# NameError: name 'add_and_multiply' is not defined

이 때 사용하는 방법이 __init__.py 에서 __all__ = [ ] 를 통해 디렉토리의 모듈을 넣어주면 된다

# __init__.py
__all__ = ['add_and_multiply']
# main.py
from calculator import *
if __name__ == '__main__':
    print(add_and_multiply.add_and_multiply(1, 2))
# 5

정상적으로 출력이 되는 것을 확인할 수 있

0개의 댓글

관련 채용 정보