[Python]How import statement finds modules and packages

๋ฐ•ํ˜„ํฌยท2020๋…„ 9์›” 21์ผ
0

๐ŸงHow import statement finds modules and packages

1.Import Search ์ˆœ์„œ

๋ชจ๋“ˆ์ด๋‚˜ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด import๋ฅผ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
import๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„  ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ํŒŒ์ผ์ด๋‚˜ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์–ด๋””์— ์žˆ๋Š”์ง€ ํŒŒ์ด์ฌ์ด ์ฐพ์•„์•ผ ํ•˜๋Š”๋ฐ
ํŒŒ์ด์ฌ์€ ๋ชจ๋“ˆ/ํŒจํ‚ค์ง€๋ฅผ ์ฐพ์„๋•Œ ์•„๋ž˜์˜ ์žฅ์†Œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ณด๋ฉด์„œ ์ฐพ์Šต๋‹ˆ๋‹ค.

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

1.sys.modules

ํŒŒ์ด์ฌ์ด ๋ชจ๋“ˆ์ด๋‚˜ package๋ฅผ ์ฐพ๊ธฐ์œ„ํ•ด ๊ฐ€์žฅ ๋จผ์ € ํ™•์ธํ•˜๋Š” ๊ณณ์œผ๋กœ dictionary ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ฏธ import๋œ ๋ชจ๋“ˆ๊ณผ package๋“ค์„ ์ €์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ฆ‰, ํ•œ๋ฒˆ import๋œ ๋ชจ๋“ˆ๊ณผ package๋“ค์€ ํŒŒ์ด์ฌ์ด ๋˜ ๋‹ค์‹œ ์ฐพ์ง€ ์•Š๊ณ  sys.modules๋ฅผ ํ™•์ธํ•˜์—ฌ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
ํ•œ ๋ฒˆ ์ด์ƒ ์‚ฌ์šฉ๋˜์—ˆ๊ฑฐ๋‚˜ ์ด๋ฏธ ๋‚ด์žฅ ๋˜์–ด ์žˆ๋Š” module์ด๋‚˜ ํŒจํ‚ค์ง€๋งŒ ์กด์žฌํ•˜๋ฏ€๋กœ ์ƒˆ๋กญ๊ฒŒ import๋˜๋Š” ๊ฒƒ๋“ค์€ sys.modules ์—์„œ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

import sys

print(sys.modules)
'''
{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>,...}
'''

2.built-in modules

ํŒŒ์ด์ฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํŒŒ์ด์ฌ ๊ณต์‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค ์ž…๋‹ˆ๋‹ค.
Built-in ๋ชจ๋“ˆ๋“ค์€ ์ด๋ฏธ ํŒŒ์ด์ฌ์— ํฌํ•จ๋˜์–ด ๋‚˜์˜ค๋ฏ€๋กœ ํŒŒ์ด์ฌ์ด ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

3.sys.path

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ณด๋Š” ์žฅ์†Œ๊ฐ€ ๋ฐ”๋กœ sys.path ์ž…๋‹ˆ๋‹ค.
sys.path๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ list์ด๋ฉฐ string ์š”์†Œ๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” list ์ž…๋‹ˆ๋‹ค.
๊ฐ string ์š”์†Œ๋“ค์€ ๋‹ค์Œ ์ฒ˜๋Ÿผ ๊ฒฝ๋กœ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋ฏ€๋กœ ํŒŒ์ด์ฌ์€ list์˜ ๊ฐ ๊ฒฝ๋กœ๋ฅผ ํ•˜๋‚˜ ํ•˜๋‚˜ ํ™•์ธํ•˜๋ฉด์„œ ํ•ด๋‹น ๊ฒฝ๋กœ์— import ํ•˜๊ณ ์ž ํ•˜๋Š” package๊ฐ€ ์œ„์น˜ํ•ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ sys ๋Š” ํŒŒ์ด์ฌ์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๋‹ค์Œ ์ฒ˜๋Ÿผ sys ๋ชจ๋“ˆ์„ import ํ•ด์„œ sys.modules์™€ sys.path ๋ฅผ ์ถœ๋ ฅํ• ์ˆ˜๋„ ์žˆ๊ณ  ์ˆ˜์ • ํ•  ์ˆ˜ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

import sys

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

์ •๋ฆฌ๋ฅผ ํ•˜์ž๋ฉด, ํŒŒ์ด์ฌ์€ import ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ชจ๋“ˆ๊ณผ package๋ฅผ ์ฐพ์„๋•Œ์— ๋จผ์ € sys.modules๋ฅผ ๋ณด๊ณ , ์—†์œผ๋ฉด ํŒŒ์ด์ฌ built-in ๋ชจ๋“ˆ๋“ค์„ ํ™•์ธ ํ•˜๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ sys.path์— ์ง€์ •๋˜์–ด ์žˆ๋Š” ๊ฒฝ๋กœ๋“ค์„ ํ™•์ธํ•ด์„œ ์ฐพ์Šต๋‹ˆ๋‹ค.
sys.path ์—์„œ๋„ ๋ชป์ฐพ์œผ๋ฉด ModuleNotFoundError ์—๋Ÿฌ๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

2. Absolute Path & Relative Path

ํŒŒ์ด์ฌ์˜ built-in ๋ชจ๋“ˆ๊ณผ pip ์„ ํ†ตํ•ด ์„ค์น˜ํ•œ ์™ธ๋ถ€ ๋ชจ๋“ˆ ๋ฐ package๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ import ํ•˜๋Š”๋ฐ ํฐ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Built-in ๋ชจ๋“ˆ์€ ์„ค์น˜ํ•˜๋ฉด์„œ ๋‚ด์žฅ๋˜์–ด ์žˆ๊ณ , pip์œผ๋กœ ์„ค์น˜ํ•œ ์™ธ๋ถ€ ๋ชจ๋“ˆ์€ ์ž๋™์œผ๋กœ site-packages ๋ผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ์— ์„ค์น˜๊ฐ€ ๋˜๋Š”๋ฐ, ์ด site-packages ๋Š” sys.path์— ์ด๋ฏธ ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ๋•Œ๋ฌธ์— ์ฐพ๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ์ง์ ‘ ๊ฐœ๋ฐœํ•œ local package ์ž…๋‹ˆ๋‹ค. ์ง์ ‘ ๊ฐœ๋ฐœํ•œ local package๋ฅผ import ํ•  ๋•Œ๋Š” ํ•ด๋‹น package์˜ ์œ„์น˜์— ๋งž๊ฒŒ import ๊ฒฝ๋กœ๋ฅผ ์ž˜ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Local package๋ฅผ import ํ•˜๋Š” ๊ฒฝ๋กœ์—๋Š” absolute path ์™€ relative path ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๋กœ์˜ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

โ””โ”€โ”€ my_app
    โ”œโ”€โ”€ main.py
    โ”œโ”€โ”€ package1
    โ”‚   โ”œโ”€โ”€ module1.py
    โ”‚   โ””โ”€โ”€ module2.py
    โ””โ”€โ”€ package2
        โ”œโ”€โ”€ __init__.py
        โ”œโ”€โ”€ module3.py
        โ”œโ”€โ”€ module4.py
        โ””โ”€โ”€ subpackage1
            โ””โ”€โ”€ module5.py

2-1. Absolute path

Absolute path๋Š” ๋ง ๊ทธ๋Œ€๋กœ ์ ˆ๋Œ€ ๊ฒฝ๋กœ ์ž…๋‹ˆ๋‹ค. import๋ฅผ ํ•˜๋Š” ํŒŒ์ผ์ด๋‚˜ ๊ฒฝ๋กœ์— ์ƒ๊ด€์—†์ด ํ•ญ์ƒ ๊ฒฝ๋กœ๊ฐ€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.๊ทธ ๋ง์€ ์ƒ๋žต์ด๋‚˜ ์ถ•์•ฝ๋˜์ง€ ์•Š๊ณ  ๋ช…ํ™•ํžˆ ๋ช…์‹œ๋œ ๊ฒฝ๋กœ๋ฅผ ๋œปํ•ฉ๋‹ˆ๋‹ค. ์–ด๋””์—์„œ ์“ฐ๋“  ํ•ญ์ƒ ๊ฐ™์•„์„œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ํ—ท๊ฐˆ๋ฆฌ์ง€ ์•Š๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Absolute path๋ฅผ ์‚ฌ์šฉํ•ด ์œ„ ํ”„๋กœ์ ํŠธ์˜ package1 ๊ณผ package2๋ฅผ import ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

๊ฒฝ๋กœ๋“ค์˜ ์‹œ์ž‘์ ์ด ์ „๋ถ€ "my_app" ํ”„๋กœ์ ํŠธ์˜ ๊ฐ€์žฅ ์ตœ์ƒ์œ„ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.์˜ˆ๋ฅผ ๋“ค์–ด, subpackage1์˜ module5 ๋ชจ๋“ˆ์˜ function2 ํ•จ์ˆ˜๋ฅผ import ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ ๊ฒฝ๋กœ๋ฅผ ๊ฑฐ์น˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

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

my_app ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ๋Š” ์–ด๋Š ํŒŒ์ผ, ์–ด๋Š ์œ„์น˜์—์„œ import ํ•˜๋˜์ง€ ๊ฒฝ๋กœ๊ฐ€ ํ•ญ์ƒ ์œ„์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ local package๋ฅผ import ํ• ๋•Œ๋Š” absolute path๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
๋‹ค๋งŒ absolute path๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํ•œ๊ฐ€์ง€ ๋‹จ์ ์ด ์žˆ๋Š”๋ฐ ๋ฐ”๋กœ ๊ฒฝ๋กœ๊ฐ€ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์ด๋Ÿฌํ•œ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด์„œ relative path๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2-2.Relative path

Relative path ๋Š” absolute path์™€ ๋‹ค๋ฅด๊ฒŒ ํ”„๋กœ์ ํŠธ์˜ ์ตœ์ƒ๋‹จ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฒฝ๋กœ๋ฅผ ์žก๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ import ํ•˜๋Š” ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฒฝ๋กœ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ผ๋ฐ˜์ ์œผ๋กœ relative path๋Š” local package ์•ˆ์—์„œ ๋‹ค๋ฅธ local package๋ฅผ import ํ• ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, package2์˜ module3์—์„œ package2์˜ ํ•˜์œ„ package์ธ subpackage1์˜ module5์˜ function2 ํ•จ์ˆ˜๋ฅผ importํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋‹ค์Œ ์ฒ˜๋Ÿผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# package2/module3.py

from .subpackage1.module5 import function2

์—ฌ๊ธฐ์„œ dot(.)์€ import๊ฐ€ ์„ ์–ธ๋˜๋Š” ํŒŒ์ผ์˜ ํ˜„์žฌ ์œ„์น˜๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ์œ„์น˜๋Š” package2/module3.py ์ด๋ฏ€๋กœ ํ˜„์žฌ ์œ„์น˜์—์„œ๋ถ€ํ„ฐ ์›ํ•˜๋Š” ๋ชจ๋“ˆ์˜ ๊ฒฝ๋กœ๋งŒ ์„ ์–ธํ•ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ dot 2๊ฐœ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, dot 2๊ฐœ(..) ๋Š” ํ˜„์žฌ์œ„์น˜์—์„œ ์ƒ์œ„ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ๊ฐ€๋Š” ๊ฒฝ๋กœ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.

Relative path๋Š” ์„ ์–ธํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ๋กœ์˜ ๊ธธ์ด๋ฅผ ์ค„์—ฌ์ค€๋‹ค๋Š” ์žฅ์ ์€ ์žˆ์ง€๋งŒ ํ—ท๊ฐˆ๋ฆฌ๊ธฐ ์‰ฝ๊ณ  ํŒŒ์ผ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๊ฒฝ๋กœ ์œ„์น˜๋„ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•˜๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์›ฌ๋งŒํ•œ ๊ฒฝ์šฐ absolute path๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑธ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

๐Ÿคจ๊ฐœ๋… ์ •๋ฆฌ & ๋ฌธ์ œ ํ’€์ด

1.sys.modules ์™€ sys.path์˜ ์ฐจ์ด์ ์„ ์„œ์ˆ ํ•ด ์ฃผ์„ธ์š”.

sys.modules

  • ํŒŒ์ด์ฌ์ด ์ œ์ผ๋จผ์ € ๋ชจ๋“ˆ์ด๋‚˜ ํŒจํ‚ค์ง€๋ฅผ ์ฐพ๋Š”๊ณณ
  • ๋”•์…”๋„ˆ๋ฆฌ๊ตฌ์กฐ
  • import ๋˜์žˆ๋Š” ๋ชจ๋“ˆ๊ณผ ํŒจํ‚ค์ง€ ์ €์žฅ (๋‹ค์‹œ ์ฐพ์ง€ ์•Š์•„๋„ ๋จ)

sys.path

  • ๋ชจ๋“ˆ๊ณผ ํŒจํ‚ค์ง€๋ฅผ 1,2๋ฅผ ์ฐพ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ sys.path๋ฅผ ์ฐพ์Œ
  • ๋ฆฌ์ŠคํŠธ๊ตฌ์กฐ(string ์š”์†Œ๋ฅผ ๊ฐ€์ง„ ๋ฆฌ์ŠคํŠธ)

2. sys ๋„ import ํ•ด์•ผํ•˜๋Š” ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค. ํŒŒ์ด์ฌ์€ sys ๋ชจ๋“ˆ์˜ ์œ„์น˜๋ฅผ ์–ด๋–ป๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์„๊นŒ์š”?

'sys': <module 'sys' (built-in)>

sys๋ชจ๋“ˆ์€ ์ด๋ฏธ built-in ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— built-in module๋“ค์ด ์žˆ๋Š” ๋ถ€๋ถ„์—์„œ ์ฐพ์„์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์œ„์—์„œ ์„ค๋ช…ํ•œ๋“ฏ์ด sys ๋ชจ๋“ˆ์„ import ํ•ด์„œ sys.modules์™€ sys.path ๋ฅผ ์ถœ๋ ฅ, ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

3. Absolute path์™€ relative path์˜ ์ฐจ์ด์ ์„ ์„œ์ˆ ํ•ด ์ฃผ์„ธ์š”

Absolute path

  • ์ ˆ๋Œ€๊ฒฝ๋กœ
  • ๊ฒฝ๋กœ์˜ ์‹œ์ž‘์ ์ด ๊ฐ€์žฅ ์ตœ์ƒ์œ„ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ
  • ๊ทธ๋ž˜์„œ importํ•˜๋Š” ๊ฒฝ๋กœ์™€ ์ƒ๊ด€์—†์ด ๋Š˜ ๋™์ผ
  • ๊ฒฝ๋กœ๊ฐ€ ๊ธธ์–ด์ง€๋Š” ๋‹จ์ ์ด ์žˆ์Œ

Relative path

  • ์ƒ๋Œ€๊ฒฝ๋กœ
  • ๊ฒฝ๋กœ์˜ ์‹œ์ž‘์ ์ด import ํ•˜๋Š” ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ
  • ๊ทธ๋ž˜์„œ ๊ฒฝ๋กœ๊ฐ€ ๋™์ผํ•˜์ง€ ์•Š์Œ
  • ๊ฒฝ๋กœ๋Š” ์งง์•„์ง€์ง€๋งŒ ํ—ท๊ฐˆ๋ฆด ์œ„ํ—˜๋„๊ฐ€ ๋†’์Œ

0๊ฐœ์˜ ๋Œ“๊ธ€