Modules & Packages

jinatra·2021년 8월 10일
0

Python

목록 보기
12/15
post-thumbnail

Modules & Packages


Modules

Module (모듈)

변수나 함수, 또는 클래스를 모아놓은 파일

모듈을 만드는 이유는 아래와 같다.

  • 다른 파일에서 재사용이 가능하게 하기 위함
  • 전체 코드가 한 파일에 넣기에는 너무 커졌을때 여러 파일로 나누어서 정리를 하기 위함

Making Module

.py 파일을 만든 후 해당 파일 안에 재사용하고자 하는 변수나 함수, 또는 클래스 등을 구현하면 된다.

# my_module.py

my_module_var = 7
 
def my_module_func():
    return "Hello!"
 
class MyModuleClass:
    pass

Import Module

import module_name

import 키워드와 불러오고자 하는 모듈의 파일명을 입력하면 된다.
(이때 확장자 .py는 생략)

모듈을 불러온 다음에는 .(dot)을 통해 모듈의 원하는 변수/함수/클래스 구현 가능

<모듈 이름>.<모듈에서 사용하길 원하는 변수/함수/클래스 이름>

모듈 my_module의 함수 my_module_func를 호출하고자 할 때는 아래와 같이 시행할 수 있다.

# example
my_module.my_module_func()

모듈 이름을 앞에 붙여줘야 하는 이유?

파이썬이 어느 파일을 봐야 해당 함수를 찾을수 있는지 알 수 있기 때문

만일 모듈 이름을 안붙어주면 파이썬은 모듈의 파일을 보지 않고 해당 파일에서만 함수를 찾을려고 하기에 꼭 모듈 이름을 앞에 붙여줘야 한다.


Import Module II

from <모듈 이름> import <함수/변수/클래스1>, <함수/변수/클래스2>, ..., <함수/변수/클래스N>

my_module 모듈에서 my_module_func 함수와 my_module_var 변수를 import 하고자 한다면 다음처럼 가능

from my_module import my_module_func, my_module_var
 
print(my_module_var)
my_module_func()

from.. import.. 방식을 사용하는 이유?

모듈 이름을 붙이지 않고 곧바로 원하는 함수나 변수 그리고 클래스를 호출할 수 있기에 모듈에서 사용하고자 하는 부분이 명확할 때 사용한다.

또한,
별표 * 를 사용하면 해당 모듈의 모든 요소가 곧바로 import 된다.

* 사용이 권장되지 않는 이유?

local scope를 가지고 있는 다른 변수/함수/클래스 들과 이름 충돌이 날 수 있는데, 만일 이름 충돌이 일어났을 경우 알기가 쉽지 않을수 있기 때문


Import As

from module_name import variable/function/class_name as new_name

만약 모듈을 두개 이상 불러와야 하는데, 두 모듈 안에 yo_maker()라는 함수가 존재할 경우 충돌이 일어날 수 있다.

이때 import as 키워드를 사용하여 새로운 이름을 부여한 후, 해당 파일에서 사용할 수 있다.

# example 

from my_module  import my_func as f1
from my_module2 import my_func as f2
from my_module3 import function_with_name_too_long as f3
 
f1()
f2()
f3()

그럼 module 이름에도 새로운 이름을 부여할 수 있는지?

당연히 module 이름 자체에도 새로운 이름을 부여할 수 있다.

# example

import my_module as m1
 
m1.my_module_func()

Packages

Package (패키지)

여러 파일에 나누어져 있는 코드들도 다른 곳에서 하나의 module로 불러와서 사용할 수 있도록 해주는것

Package는 파이썬 파일들로 이루어져 있는 디렉토리(directory)가 하나의 package가 되고, 해당 디렉토리의 이름이 package 이름이 된다.


Import Package

dot notation을 이용하여 해당 패키지의 원하는 모듈을 import하면 된다.

# example

import pkg.mod1
from pkg.mod2 import func2
 
pkg.mod1.func2()
func2()

Package Initialization

__init__.py 파일

파이썬은 __init__.py 파일을 통해 package 초기 설정을 가능하게 해준다.

Package 안에 __init__.py 파일이 있으면 package가 import 될때 __init__.py 파일의 코드들이 자동으로 실행


__init__.py 파일의 기능

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

__init__.py 을 통해 어떻게 경로를 줄이는지?

"__init__.py 파일에 먼저 한번 import를 해줌으로써 경로의 길이를 줄일 수 있다."


만약 내가 `pkg`에서 `mod1`의 `func2` 라는 함수를 `import` 하여 사용하기 위해서는 다음과 같이 해야한다.
import pkg.mod1
 
pkg.mod1.func2()

매우 길지 않은가? func2 함수를 이용할 때마다 이렇게 써줘야하니 굉장히 번거로운 일이 아닐 수 없다.

이때 __init__.py 파일을 통해 함수의 경로를 줄여줄 수 있다.

# __init__.py
from .mod1 import func2
# main.py
from pkg import func2
 
func2()

__all__ 변수 지정 in __init.py__ 파일

내부적으로만 사용되어야 하는 함수가 있을 때, 이러한 함수가 package 외부에서 import되어 사용되는 것을 막기 위해서는 __all__ 변수를 지정해 줄 수 있다.

package를 통해 import 될 수 있는 요소들은 모두 __all__ 변수를 통해 정의된다.

__all__ 변수 지정으로 인한 import 요소 제한

__all__ 변수의 default 값은 모든 함수/변수/클래스이므로, __all__ 변수를 따로 정의해줌으로 인해 import 될 수 있는 요소들을 제한할 수 있다.

__all__ 변수의 list 성질

__all__ 변수는 string 값의 요소를 가지고 있는 list이므로, import 되길 원하는 요소들을 string으로 list에 선언해주면 된다.

# __init__.py
from .mod1 import func2
from .mod2 import func3
 
__all__ = ['func2', 'func3']
# main.py
from pkg import *
 
func2()
func3()
func4() ## <== Error. func4 함수는 __all__ 에 정의되지 않았으므로 import 될 수 없음.

Using other one's Package

pip install pkg_name

파이썬의 package manager인 pip라는 툴을 사용하여 다른 사람의 package를 import할 수 있다.

예를 들어 Django를 설치하고자 하면, 터미널에서 다음과 같이 입력하면 된다.

pip install Django 




Take Away

어렵다 어려워!!

모듈까지는 어찌저찌 이해가 되는데.. 패키지로 넘어가고부턴 확실히 어려워지기 시작했다.
패키지에서도 __init__.py 파일과 __all__ 라는 변수를 다뤘는데, 아직 실제로 써본 적이 없으니 확 와닿지 않는 듯 하다..


profile
으악

0개의 댓글