[TIL] Python: Modules

hojin11choi·2021년 1월 14일
0

Python

목록 보기
4/4
post-thumbnail

1. sys

1-1. Understanding sys

Python documentation 에 의하면:

This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter. It is always available.

sys 모듈은 파이썬 인터프리터가 제공하는 시스템에 특화된 함수나 변수를 제공해준다. 그리고 항상 사용가능하다. 즉, built-in module이다.

그래서 파이썬에서 sys 모듈을 import 할때도 경로를 적지 않는다.

import sys 	#from ??? 필요 없다 !

1-2. sys.modules vs sys.path

  1. sys.modules 는 이미 import된 module과 package가 저장되어있는 dictionary이다. 그러므로 한번 import된 모듈과 패키지는 파이썬이 다시 찾지 않아도 되게 하는 기능을 가진다. 하지만 그렇기 때문에 새로 import할 모듈은 찾을 수 없다.

  2. sys.path는 모듈을 찾을 수 있는 모든 위치가 string으로 저장되어있는 list이다. 파이썬은 list의 각 경로를 개별적으로 확인하면서 해당 경로에 import 하고자 하는 package가 위치해 있는지 확인한다.


2. Absolute path vs Relative path

다음과 같은 디렉토리가 있다고 가정해보자.


└── project
    ├── package1
    │   ├── module1.py
    │   └── module2.py      	#contains function1
    └── package2     
        ├── __init__.py     	#contains class1
        ├── module3.py
        ├── module4.py
        └── subpackage1
            └── module5.py 	#contains function2

2-1. Absolute path

Absolute path는 절대 경로이다. 즉, 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는다.

위의 디렉토리와 같은 상황에서 function 1 을 absolute import 하고 싶은 경우에:

from package1.module2 import function1
  • 장점: 확실하고 단순하다. 현재 위치가 바뀌어도 똑같다.
  • 단점: 복잡한 디렉토리에 경우에는 말이 너무 길어져서 번거로워진다.

단점과 같은 상황은 아래의 예시를 통해 확인할 수 있다.
(정말 길다. 심지어 한 줄안에 다 안 들어가서 잘린다.)

from package1.subpackage2.subpackage3.subpackage4.module5 
import function6

이런 경우를 해결하기 위해서 relative path가 존재한다!

2-2. Relative path

Relative path는 상대 경로이다. 즉, import하는 위치를 기준으로 경로를 정의한다. 그러므로 relative path는 local package 안에서 다른 local package를 import 할때 사용된다.

  • 장점: 현재 위치를 기준으로 하여 간단하게 작성할 수 있다.
  • 단점: 한계가 있다 (feat. main module)

단점은 Wecode assignment 1.에서 확인할 수 있다 :)

relative import의 예시들이다:

from .some_module import some_class
from ..some_package import some_function
from . import some_class

. : 점 한개는 불려오는 모듈이나 패키지가 현재 위치와 같은 디렉토리에 있다는 뜻이다. (상대적 위치가 같다고 이해하면 편하다)

..: 점 두개는 현재 위치의 바로 상위 단계의 디렉토리 (parent directory) 라는 뜻이다.

그렇다면 점 세개는 grandparent directory 이다.
이런 식으로 점 개수를 늘려나갈 수 있다.


WeCode assignment

1. Relative import이 안되는 경우: main module

add_and_multiply 에 multiplication module의 multiply 함수를 import 하기 위하여 main.py 에는 다음과 같은 코드를 작성하였다.

# 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))

에러 메시지는 다음과 같다.

ImportError: attempted relative import with no known parent package

즉, top-level 패키지를 넘어 relative import 를 시도했다는 것이다.

Python 홈페이지에 따르면:

Note that relative imports are based on the name of the current module. Since the name of the main module is always "main", modules intended for use as the main module of a Python application must always use absolute imports.

이 말은 즉,

상대 경로를 사용하여 import를 시도할 때 현재 module 의 이름을 기반으로 해야한다. **main module의 이름은 항상 __main__ 이기 때문에 절대 경로를 사용해야한다. **

이제 위의 문제에서 왜 에러가 발생했는지 알 수 있다.

calculator에서 main.py은 calculator package에 속한 파일이 아니다. 고로 main.py가 속한 곳은 __main__ 이 되는 것이다. 그렇기 때문에 절대 경로를 사용해야한다.


2. add_and_multiply.py 에서의 import

multiply를 import하기 위해 두가지 path를 모두 써보았다:

  1. absolute path
    from calculator.multiplication import multiply

  2. relative path
    from .multiplication import multiply

결과는 같고, 두 경로 모두 가능하다.

main module과 add_and_multiply의 차이점은 다음과 같다;

  1. main은 같은 package안에 있지 않기 때문에 상대 경로를 사용할 수 없다.
  1. add_and_multiply는 같은 package안에 있기 때문에 절대 경로, 상대 경로 모두 사용 가능하다.
profile
Relish life-long learning

0개의 댓글