Python-module, package

강현구·2021년 12월 5일
0

Python

목록 보기
16/21

import module

모듈을 import할 때는 파일 확장자(.py)를 제외한 파일 이름만 사용한다.
import my_module
모듈을 import한 후에는 모듈의 원하는 변수,함수,클래스를 사용할 수 있다.
print(my_module.my_module_var)
my_module.my_module_func()
my_module_class = my_module.MyModuleClass()

from ... import ...를 사용하면 모듈 이름을 붙이지 않고 import된 요소를 편하게 사용할 수 있다.
특히 import *로 사용하면 모듈의 모든 요소가 바로 import된다.
하지만 이렇게 사용할 경우 변수,함수,클래스의 충돌이 일어날 수 있는데 이를 알기가 쉽지 않다..

import as

많은 모듈을 쓸 경우 이름 충돌이 날 가능성이 높다.
또는 요소의 이름이 너무 길어 사용이 불편할 수도 있다.
이때 import as를 사용해서 새로운 이름으로 사용할 수 있다.

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

Package

패키지는 모듈과 마찬가지로 다른파일을 통해 불러와서 사용하는 개념이다.
차이점은 모듈보다 크고 복잡한 구성을 갖는다.
> 모듈 파일을 묶어둔 디렉토리를 말한다.
패키지도 모듈처럼 import하여 사용할수 있다.
다만, 패키지내의 원하는 모듈을 'dot notation'으로 구분해서 import해주어야 한다.

import pkg.mod1
from pkg.mod2 import func2

pkg.mod1.func2()
func2()

Initialization

패키지가 import 될 때 초기 설정을 해줘야 할 수도 있따.
파이썬에서는 __init__.py파일을 통해 초기설정을 가능하게 해준다.
__init__.py파일을 통해 다음을 할 수 있다.

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

패키지 안에 __init__.py파일이 있으면 패키지가 import될 때 __init__.py 파일의 코드가 자동으로 실행된다.
(클래스를 만들 때와 유사하다.)
package
패키지에서 'mod1' 의 'func2'를 import하기 위해서는 다음과 같이 해야한다.

import pkg.mod1

pkg.mod1.func2()

함수를 호출할 때마다 모든 경로를 다 입력해야하는 번거로움이 있다.
이럴 때, __init__.py파일을 통해 경로를 줄여줄 수 있다.
__init__.py파일에서 한번 import해주면 된다!!

# __init__.py
from .mod1 import func2
--------------------------
# main.py
from pkg import func2

func2()

또한 __init__.py로 import하는 요소를 제한할 수 있다.
이때는 __init__.py내에 __all__변수 지정으로 해당 변수 내의 요소만 import되도록 제한할 수 있다.

# __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 될 수 없음.

import문은 어떻게 대상을 찾는가

패키지(또는 모듈)가 import될 때, 파이썬은 해당 데이터가 어디에 위치하는 지를 찾을 수 있어야 import가 가능할 것이다.
파이썬은 다음 장소를 순서대로 보며 위치를 찾는다.

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

1. sus.modules

가장 먼저 확인하는 곳.
단순한 dictionary로 이미 import된 모듈,패키지를 저장하고 있다.
즉, 한번 import되면 또 다시 찾지 않도록하는 기능이다.

2. built-in modules

파이썬의 공식 제공 라이브러리.
이미 파이썬에 포함되어 나온다.

3. sys.path

마지막으로 보는 장소이다.
기본적으로 list이며 string을 요소로 갖고있다.
각 string요소는 경로값으로 표현된다.

['',
 '/Users/HYEONGU/anaconda3/bin',
 '/Users/HYEONGU/anaconda3/lib/python38.zip']

파이썬은 이 list의 경로를 하나씩 확인하며 해당 경로에 import하고자 하는 대상이 있는지 확인한다.
파이썬 내장 모듈인 sys을 import해서 sys.modules,sys.path를 출력하고 수정할 수도 있다.

위 세가지를 확인하고 대상이 없다면 ModuleNotFoundError 를 리턴한다.

절대경로, 상대경로

Local package를 import하는 경로는 절대경로(absolute)와 상대경로(relative)가 있다.

절대 경로는 import하는 파일이나 경로에 상관없이 항상 경로가 동일하다.
프로젝트 최상위 폴더부터 시작하는 경로값을 통해서 경로를 표현한다.

상대 경로는 프로젝트 최상단이 아니라 import하는 위치르 기준으로 경로를 정의한다.
경로 표현시 .(현재 위치), ..(한단계 상위위치)로 상대적인 디렉토리의 표현이 가능하다.


  1. sys.modules vs sys.path
sys.modulessys.path
가장 먼저 확인가장 나중 확인
이미 import한 모듈,패키지처음 사용하는 모듈,패키지
dictionarylist (by string data)
  1. sys의 import??
    sys모듈은 파이썬의 built-in 모듈로 파이썬에 포함되어 있는 모듈이다.
import sys
print(sys.builtin_module_names)

>('_abc', '_ast', '_codecs', '_collections', '_functools', '_imp', '_io', '_locale', '_operator', '_signal', '_sre', '_stat', '_string', '_symtable', '_thread', '_tracemalloc', '_warnings', '_weakref', 'atexit', 'builtins', 'errno', 'faulthandler', 'gc', 'itertools', 'marshal', 'posix', 'pwd', 'sys', 'time', 'xxsubtype')

출력해보면 built-in 모듈에 sys가 있음을 확인할 수 있다.

  1. 절대경로, 상대경로
절대 경로상대 경로
프로젝트 최상위 기준import위치 기준
import하는 파일 위치와 상관없이 경로가 동일하다.import하는 파일이 변경되면 경로가 변경되야 한다.
import되는 대상까지의 경로 전체 표현" . "이나 " .. "등의 상대적 위치 표현이 가능, 간단하게 표현가능하다.
  1. calcuator 패키지
    pkg

위의 구조의 패키지가 있을 때, main.py에서 상대경로로 add_and_mytiply를 import하면 다음의 에러가 발생한다.
ImportError: attempted relative import with no known parent package
단순히 import하는 모듈을 절대경로로 변경하면 에러 없이 잘 실행되는 것을 알 수 있는데,....

공식 문서도 아무리 봐도 파악이 잘 안된다.(다시 공부가 필요할 것 같다. 아래 포스팅과 공식문서를 더 보면서 확인해보자.)

공부 1
공부 2

  • @ main.py -> __name__,__main__??
    >참고
    __name__은 python의 모듈이 저장되는 변수로 import한 모듈의 이름이 들어간다. 파이썬 인터프리터를 통해 파이썬파일을 직접 실행할 경우에는 파이썬에서 자동으로 파일의 namemain이 된다. 파이썬 모듈을 import해서 사용할 경우에는 name은 원래의 모듈이름으로 설정된다.
    (다시말해 add_and_mutiply.py을 직접 실행하면, __name__에는__main__이 들어가고 다른 곳에서 불러와서 실행하면 __name__은 add_and_mutiply가 된다.)
    그러므로 만약 해당 파일의 특정 부분이 직접 실행할 때만 실행되도록 설정하고 싶다면, if __name__ == '__main__':와 같은 구분으로 조건을 걸어주면 된다.이렇게하면 if문의 수행문 내용은 import하여 사용하고자 할때에는 실행되지 않게된다.
  1. add_and_multiply.py에서 multiply함수의 절대,상대경로의 impor와 main 모듈과 차이점??
    add_and_multiply.py 에서 multiply 함수를 절대경로나 상대경로에 상관 없이 동일하게 잘 실행된다. main.py와 add_and_multiply.py파일에서 __name__을 출력하면 기본 모듈이 main로 실행됨을 확인할 수 있다.
    > main 모듈은 패키지 안에 들어있지 않기 때문에 다른 패키지나 모듈을 임포트할 때 절대경로로 불러와야 하며, 다른 경우는 절대경로든 상대경로든 상관없이 사용할 수 있다.
    main module의 특수한 규칙정도로 이해...
    (좀더 공부해보자... vscode에서 잘 실행이 안된다.)

  2. __init__.py 파일의 역할

  • 파이썬에서 패키지의 초기 설정을 할 수 있다.
    > 패키지 안에 __init__.py파일이 있으면 패키지가 import될 때 __init__.py의 코드들이 자동으로 실행된다.
  • __init__.py을 통해 import할 때 경로의 길이를 줄여준다.
    > __init__.py파일에 모듈의 요소를 import하고, 그 요소를 패키지 내 다른 모듈에서 import할 때,
from (pkg name) import (module elm)

와 같이 상대적으로 더 간단한 표현으로 할 수 있다.

  • 패키지에서 import할 수 있는 변수/함수/클래스를 제한한다.
    __init__.py파일 내에서 __all__ 변수를 변경하면 된다.
    __all__ 변수의 리스트내에서 문자열로된 요소를 지정해주면 import할 수 있는 모듈의 요소를 제한할 수 있다.
profile
한걸음씩

0개의 댓글