sys.modules는 파이썬에서 모듈이나 패키지를 찾기 위해 가장 먼저 찾는 곳이며, 디렉토리 형식으로 되어있다.
sys.path는 가장 마지막으로 찾아보는 곳이며, list형식에 string요소들을 가지고 있다.
1 2 3 4 5 | import sys print(sys) ><module 'sys' (built-in)> | cs |
find . -name 'sysmodule.c'
입력을 통해 확인 할 수 있다.
Absolute path는 이름 그대로 절대 경로이다. 파일의 위치에 상관없이 항상 경로가 동일하다. 항상 최상단의 디렉토리를 기준으로 경로를 잡는다.
단점은 경로가 길어질 수 있다는 점
relative path는 상대경로이다. import하는 위치를 기준으로 경로를 정의한다.
일반적으로 local package안에서 다른 local package를 import할때 사용한다.
. ==> 현재 위치 경로를 나타낸다.
.. ==> 현재 위치의 상위 경로를 나타낸다.
단점은 헷갈리기 쉽고 파일 위치가 변경되면 경로가 전체적으로 바뀐다.
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))
# 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))
add_and_multiply.py
from .multiplication import multiply
# from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
from .multiplication import multiply
# from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
multiplication.py
def multiply(a,b):
return(a*b)
이런 패키지를 만들었을 때, main.py에서 상대경로로 add_and_mutiply를 import했을 때 발생하는 에러를 확인하고, main module 에서는 패키지의 모듈을 어떻게 임포트 해야하는가?
에러
ImportError: attempted relative import with no known parent package
이 문제를 해결하려면
if __name__ == '__main__
이 부분부터 이해하고 가야된다. 코드 그대로 해석하면 '__name__이라는 변수의 값이 __main__이라면 아래의 코드를 실행하라.' 라는 뜻이다.
파이썬은 C언어나 Java랑은 다르게 main함수가 존재하지 않는다.
__name__은 현재 모듈의 이름을 담고 있는 내장변수이다. 이 변수는 직접 실행된 모듈의 경우 __main__이라는 값을 가지게 되고 직접 실행되지않고 import된 모듈은 모듈의 이름(파일명)을 가지게 된다.
예를 하나들어보자.
#module.py
def hello():
print("Hello")
print(__name__)
#main.py
import module
print(__name__)
module.hello()
module
__main__
Hello
즉, 직접 실행한 파일은 __name__ 내장변수에 __main__이라는 값이 들어가고 import된 모듈은 각 모듈의 이름이 들어간다는것을 알 수 있다.
다시 문제로 돌아가서 저 한줄로 인해 최상위 모듈이 main.py가 되면서 상대경로로 calculator를 import할 수 없던 것이다. 이를 해결하기 위해선 절대 경로를 이용해 import를 하면 사용가능하다.
상대경로
from .multiplication import multiply
> ImportError: attempted relative import with no known parent package
절대경로
from calculator.multiplication import multiply
> ModuleNotFoundError: No module named 'calculator'
믿었던 절대 경로도 오류라니 무엇이 문제일까?
절대경로를 import할때는 현재의 디렉토리가 sys.path에 포함된다.즉, 같은 디렉토리 내에 존재함으로
from multiplication import multiply
이렇게 실행하면 된다.
__init__.py 파일은 해당 디렉토리가 패키지의 일부임을 알려주는 역할을 한다. 패키지가 포함된 디렉토리에 __init__.py 파일이 없으면 패키지로 인식이 되지않는다.
또한 특정 디렉토리의 모듈을 *을 사용하여 import할 때 해당 디렉토리내의 __init__.py 파일에 __all__변수를 설정하고 import할 수 있는 모듈을 정의해 주어야 한다.
⛔️ 참고