TIL #41 : [Python] Importing Modules, Packages

셀레스틴 허·2021년 1월 17일
0
post-thumbnail
post-custom-banner

Modules


파이썬에서 모듈을 변수나 함수 그리고 클래스를 모아놓은 파일이다.
모듈을 따로 모아놓는 이유는

  • 다른 파일에서 재사용할 수 있으며
  • 전체 코드가 한 파일에 넣기에는 너무 커졌을 때 여러 파일로 나누어서 정리를 하기 위해서다.

How to make a module file

  1. 파일을 만들고 재사용하고 싶은 함수, 클래스 또는 변수를 구현하면 된다.
  2. 그 후 해당 파일을 불러와서 사용하면 된다. 모듈을 불러와 사용하기 위해서는 import라는 키워드르 사용하면 된다
import [Module]

3.주의해야할 점은: 모듈을 import 할 때 확장자인 .py를 제외하고 파일 이름만 사용해서 import 해야한다.
4. 원하는 모듈을 import한 후:

import [Module].[The Variable, Function or Class you want to use from the Module]

import하고 싶은 함수, 변수, 클래스 앞에 모듈 이름을 붙여줘여하는 이유는 그래야지 파이썬이 어늘 파일을 봐야 해당 함수를 찾을 수 있는지 알 수 있기 때문이다. 모듈 이름을 안붙여주면 파이썬은 모듈의 파일을 보지 않고 해당 파일에서 함수를 찾으려고 한다. (즉 에러가 난다) 이러한 구조를 'name space'라고 한다. 이름, 공간, 영역을 알려주기 때문이다.

Other ways to import modules

import 키워드 외에 from import 키워드를 사용해서 모듈을 불러올 수 있다.

from [Module] import [Function, Variable, Class(1)], [Function, Variable, Class(2)], ...., [Function, Variable, Class(N)]

예시)

from go_home import drink_water_func, charge_phone_var, watch_movie_class

print(charge_phone_var)
drink_water_func()

from import 키워드를 사용래 모듈을 불러오는 이유는 모듈 이름을 붙이지 않고 곧바로 원하는 함수나 변수 그리고 클래스를 호출할 수 있기 때문이다. 모듈에서 사용하는 것이 명확할 때 from import을 사용하는게 편리하다.

다음처럼 ( * )를 사용해 해당 모듈에 있는 모든 요소를 import할 수 있다. 하지만 권장하지 않는다. local scope를 가지고 있는 다른 변수/함수/클래스 들과 이름 충돌이 발생할 경우 놓칠 수 있기 때문이다.

Import as

동일한 이름의 함수를 여러 모듈에서 가져올 경우 이름 충돌할 발생할 수 있기 때문에 이름을 바꿔줘야 한다. 또는 요소의 이름이 너무 긴 경우 import as 키워드를 사용해서 새로운 이름을 지어줄 수 있다.

from jasons_house import do_homework as jasons_hw
from justins_house import do_homework as justins_hw
from esthers_house import do_homework_as_soon_as_possible as esthers_hw

jasons_hw()
justins_hw()
esthers_hw()

** 모듈 이름도 as를 사용해서 새로운 이름을 줄 수 있다

import jasons_house as haunted_house

haunted_house.ghost()

Packages


패키지는 더 크고 복잡한 코드지만 불러와서 사용하는 점에서 모듈과 똑같다. 한 파일에 많은 양의 코드를 넣기 비효율적일 수 있다. 그런 경우 여러 파일에 나누어서 코드를 관리하는게 효과적이다. 이렇게 여러 파일에 나누어져서 코들 관리하는 것이 효과적이다.

여러 파일에 나누어져있는 코드들도 다른 곳에서 하나의 모듈로 불러와서 사용할 수 있도록 만들어주는게 바로 패키지다.

패키지는 파이썬 파일들로 이루어져 있는 디렉토리가 하나의 패키지가 된다. 그리고 해당 디렉토리의 이름이 패키지 이름이 된다.

패키지는 일반 모듈처럼 import해 사용할 수 있다. 다만 차이점은 클래스 객체를 사용할 때 처럼 'dot notation'으로 해당 패캐지의 원하는 모듈을 import해야 한다.

Pacakge Initialization

가끔 패키지가 import 될 때 초기 설정을 해줘야 할 때가 있다.

패키지 안에 _init.py__ 파일이 있으면 패키지가 import될 때 _init.py__ 파일의 코드들이 자동으로 실행된다.

_init.py__파일이 할 수 있는 일:

  • import할 때 경로의 총 길이 줄여주기
  • package에서 import할 수 있는 변수, 함수, 클래스 제한하기
  • 그 외 package가 import될 때 꼭 먼저 실행되어야 하는 코드들

매번 모든 경로를 다 타입해줘야하는 불편함을 개선할 수 있다.

#init.py 
from module_one import function_one
#main.py
from pkg import function_one

그 외에 __all__같은 변수를 지정해서 package 외부에서 import 되어 사용되는 것을 막을 수 있다.

How import statements locate modules and pacakges


import abc

여기서 abc는 단순한 파이썬 파일(모듈)이거나 파이썬 파이들을 담고 있는 디렉토리(패키지)다.

Locating modules, packages

파이썬은 3 가지 장소를 순서대로 보면서 찾는다:

sys.modules >> built-in modules >> sys.path

1. sys.modules

  • 파이썬이 모듈이나 package를 찾기 위해 가장 먼저 확인하는 곳이다.

  • sys.modules는 단순한 딕셔니리다. 이미 import된 모듈과 package들을 저장하고 있다.

  • 즉 한번 import된 모듈과 package는 파이썬이 다시 찾지 않도록 만들어진 기능이다.

  • 새로 import된 모듈은 sys.modules에서 찾을 수 없다.

    2. built-in modules

  • 파이썬에서 제공하는 파이썬 공식 라이브러리들.

  • built-in 모듈들은 이미 파이썬에 포함되어 나오므로 파이썬이 쉽게 찾을 수 있다.

    3. sys.path

  • 파이썬이 마지막으로 보는 장소다.

  • 기본적으로 string 요소들을 가지고 있는 list다.

  • 각 string 요소들은 다음처럼 경로를 나타낸다.

  • 그러므로 파이썬은 list의 각 경로 하나하나 확인하면서 해당 경로에 import하고자 하는 package가 있는지 확인한다.

    참고

    sys는 파이썬에 포함되어 있는 모듈이다. sys 모듈을 import해서 sys.modules, sys.path를 출력/수정할 수 있다.

import sys

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

Absolute, Relative Path

파이썬의 built-in 모듈과 pip을 통해 설치한 외부 파일(site-packages)를 import하는데 큰 어려움은 없을 것이다. 그러나 직접 개발한 local pacakge는 import 경로를 잘 선언해야 한다.

Local Package를 import하는데 두가지 방법이 있다:
1. Absolute Path
2. Relative Path

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

Abosolute Path

윗 코드를 예시로 package1package2를 절대경로로 import하면:

from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2

경로들의 시작점이 전부 my_app 프로젝트의 가장 최상위 디렉토리에서 시작하는 것을 볼 수 있다.

pacakge2에 있는 module5.py 함수를 import하고 싶을 때의 경로:

my_app => package2 => subpackage1 => module5.py

파이썬에서는 (.)을 이용해서 경로를 쓴다. my_app 프로젝트 안에 있으므로 my_app은 생략된다.

package2.subpackage1.module5.py

my_app 프로젝트 안에서는 어느 파일, 위치에서 import하던지 경로가 항상 위와 같이 동일하므로 absolute path(절대경로)이라고 부르는 것이다.

Relative Path

absolute path와 다르게 최상단 디렉토리를 기준으로 경로를 잡는게 아니라 import하는 위치를 기주능로 경로를 정의한다. relative path는 local package안에서 다른 localpackage를 import할 때 사용된다.

(.)은 import가 선언되는 파일의 현재 위치를 말한다.
(..)는 현재 위치에서 상위 디렉토리로 가는 경로다.

** Relative Path는 경로 코드 길이를 줄여주지만 헷갈리기 쉽고 파일의 위치가 바뀌면 경로 위치도 수정해야 하기 때문에 되도록 지양하는게 좋다.

(Local Pacakge) Locating multiplication.py


File Level

  1. calculator.py, main.py가 같은 레벨에 있고
  2. calculator.py 안에 해당 파일들이 있다:
    --> __init__.py
    --> add_and_multiply.py
    --> multiplication.py

The Error

main.py에서 해당 코드를 실행할 경우 다음과 같은 Import Error가 발생한다.

The Solution

"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 되는데 main module의 이름은 항상 __main__이기 때문에 main module로 쓰는 파이썬 앱은 모두 절대경로로 설정해야 한다.

add_and_multiply

from .multiplication import multiply
from .calculator.multiplication  import multiply

절대, 상대 경로 둘다 사용 가능하다. 절대경로 짱..

profile
Software Developer / 고통은 필연, 괴로움은 선택
post-custom-banner

0개의 댓글