wecode TIL day 9 (Oct 27)

Jae Hoon Shin, 신재훈, Noah·2020년 10월 27일
0

How import statement finds modules and packages

Import Search 순서

예를 들어 설명하겠습니다.
abc 라는 package를 import 하려면

import abc

이 때 abc는 단순한 파이썬 파일(모듈) or 파이썬 파일들을 담고 있는 디렉로티 (package)입니다. 그러므로 파이썬이 파일이나 디렉토리가 어디있는지 찾을 수 있어야 import 할 수 있습니다.

파이썬은 3가지 장소를 순서대로 보면서 찾습니다.
1. sys.modules
2. built-in modules
3. sys.path

sys.modules

파이썬이 모듈이나 package를 찾기위해 가장 먼저 확인하는 곳입니다.
sys.modules는 단순한 dictionary 입니다. 그리고 이미 import된 모듈과 package들을 저장하고 있습니다.
즉, 한번 import된 모듈과 package들은 파이썬이 또 다시 찾지 않아도 되도록 하는 기능을 가지고 있습니다.
그러므로 새로 import 하는 모듈은 sys.modules 에서 찾을 수 없습니다.

built-in modules

파이썬에서 제공하는 파이썬 공식 라이브러리들 입니다.
Built-in 모듈들은 이미 파이썬에 포함되어 나오므로 파이썬이 쉽게 찾을 수 있습니다.

sys.path

마지막으로 보는 장소가 바로 sys.path 입니다.
sys.path는 기본적으로 list이며 string 요소들을 가지고 있는 list 입니다.
각 string 요소들은 다음 처럼 경로를 나타냅니다:

['',
'/Users/song-eun-u/anaconda3/bin',
'/Users/song-eun-u/anaconda3/lib/python36.zip',
'/Users/song-eun-u/anaconda3/lib/python3.6',
'/Users/song-eun-u/anaconda3/lib/python3.6/lib-dynload',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/aeosa',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/IPython/extensions',
'/Users/song-eun-u/.ipython']

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 에러를 리턴합니다.

Absolute Path & Relative Path

위에 설명한 built-in 모듈 & pip를 통해 설치한 외부 모듈 및 package는 일반적으로 import 하는데 큰 문제 되지않습니다.

문제는 직접 개발한 local package 입니다. 직접 개발한 local package를 import 할때는 해당 package의 위치에 맞게 import 경로를 잘 선언해야 합니다.

Local package를 import 하는 경로에는 absolute path 와 relative path 가 있습니다.

Absolute path

왜 절대 경로인가 하니, import를 하는 파일이나 경로에 상관없이 항상 경로가 동일하기 때문입니다.

다음과 같은 프로젝트를 예를 들어 보겠습니다:

my_app 이라는 프로젝트 이며 package1과 package2 라는 2개의 package를 가지고 있습니다.
그리고 package2는 subpackage1 라는 중첩 package를 가지고 있습니다.
Absolute path를 사용해 package1 과 package2를 import 하면 다음과 같습니다.

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

예를 들어, subpackage1의 module5 모듈의 function2 함수를 import 하기 위해서는 다음 경로를 거치게 됩니다.

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

이걸 리눅스의 directory 경로 형식으로 바꾸면 다음처럼 표현 할 수 있습니다.

my_app/package2/subpackage1/module5.py

파이썬에서는 slash (/) 나 back slack() 대신에 dot (.) 을 사용해서 경로를 표현 합니다.

my_app.package2.subpackage1.module5.py

이미 my_app 프로젝트 안에 있으므로 my_app 은 생략됩니다. 그러므로 다음처럼 경로를 표현하게 되는 것입니다.

package2.subpackage1.module5.py

이걸 from import 키워드를 사용해 import 하게 되면 ?

from package2.subpackage1.module5 import function2

my_app 프로젝트 내에서는 어느 파일, 어느 위치에서 import 하던지 경로가 항상 위와 같이 동일하게 되므로 absolute path 라고 하는 것입니다.

참고로 current directory 라고 하는 현재의 프로젝트 디렉토리는 default로 sys.path 에 포함되게 됩니다.

그러므로 absolute path는 current directory 로 부터 경로를 시작하게 되는것입니다.

일반적으로 local package를 import 할때는 absolute path를 사용하면 됩니다.

다만 absolute path를 사용하게 되면 경로가 너무 길어질 수 있습니다.

그럴 땐 relative path !

Relative path 는 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는게 아니라 import 하는 위치를 기준으로 경로를 정의합니다.
그래서
일반적으로 relative path는 local package 안에서 다른 local package를 import 할때 사용됩니다.

예를 들어, package2의 module3에서 package2의 class1과 package2의 하위 package인 subpackage1의 module5의 function2 함수를 import하려고 하면 다음 처럼 할 수 있습니다.여기서 dot(.)은 import가 선언되는 파일의 현재 위치를 이야기 합니다.
현재위치는 package2/module3.py 이므로 현재 위치에서부터 원하는 모듈의 경로만 선언해주면 되는 것입니다.

또한 dot 2개를 사용할 수도 있습니다. dot 2개(..) 는 현재위치에서 상위 디렉토리로 가는 경로입니다.

Relative path는 선언해야 하는 경로의 길이를 줄여주지만 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있습니다.
그러므로 웬만한 경우 absolute path를 사용하는게 권장 됩니다.

Assignment

1. sys.modules 와 sys.path의 차이점을 서술해 주세요.
sys.modules 은
파이썬이 모듈이나 package를 찾기 위해 제일 먼저 확인하는 곳
단순한 dictionary,
이미 import된 모듈과 package들을 저장하고 있다.(한번 import된 모듈과 package들은 파이썬이 또 다시 찾지 않아도 되는기능)
therefore, 새로 import하는 모듈은 sys.modules 에서 못 찾음

sys.path는
마지막으로 찾는 장소
기본적으로 list이며 string요소를 가지고 있는 list
마지막으로 sys.path에 지정되어 있는 경로들을 확인해서 찾습니다.
sys.path 에서도 못찾으면 ModuleNotFoundError 에러를 리턴합니다.

2. sys 도 import 해야하는 모듈입니다. 파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있을까요?

sys 모듈은 이미 built-in 되어 있기 때문에 built-in-module이 있는 부분에서 찾게됩니다.

3. Absolute path와 relative path의 차이점을 서술해 주세요.

프로젝트 내에서는 어느 파일, 어느 위치에서 import 하던지 경로가 항상 위와 같이 동일하게 되므로 absolute path 라고 하는 것입니다.

참고로 current directory 라고 하는 현재의 프로젝트 디렉토리는 default로 sys.path 에 포함되게 됩니다.
그러므로 absolute path는 current directory 로 부터 경로를 시작하게 되는것입니다.
일반적으로 local package를 import 할때는 absolute path를 사용하면 됩니다.

다만 absolute path를 사용하게 되면 경로가 너무 길어질 수 있습니다.
Relative path는 선언해야 하는 경로의 길이를 줄여주지만 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있습니다.
그러므로 웬만한 경우 absolute path를 사용하는게 권장 됩니다.

4. calculator 패키지 만들기

5. main.py에서 상대경로로 add_and_mutiply 를 임포트 했을 때 발생하는 에러를 확인하고
다음의 파이썬 공식 문서를 참고해서 main module 에서는 패키지의 모듈을 어떻게 임포트 해야하는지 블로깅 해주세요.

https://docs.python.org/3/tutorial/modules.html#intra-package-references

relative import를 absolute import로 수정했다. main이기 때문에 absolute import를 해줘야하기 때문이다.

6. add_and_multiply.py에서 multiply함수를 절대경로와 상대경로도 각각 임포트 해보고 main 모듈과 차이점을 생각해보고 결과를 출력해 보세요.

add_and_multiply.py는 패키지 내부 파일로 relative import 쓸수 있다.

main.py는 실제로 패키지와 모듈을 가져와 함수를 쓰는 파일이다.
그로 인해 단독 실행 가능 여부에 있어서도 차이를 보인다.

7. init.py 파일의 역할

init.py가 존재하는 디렉토리는 package 초기 설정을 할 수 있는 역할을 한다.

--init--.py 파일이 존재하지 않는다면
패키지의 일부인지 인식을 하지 못하기 때문에
속성을 가지고 있지 않는다는 에러가 발생하게 된다.
현재는 --init--.py파일은 빈 파일이지만
package 실행 시,
--init--.py의 초기 설정이 있다면
작성 한 코드의 내용대로 자동으로 실행된다.

파이썬은 왜 프로그램의 시작점이 정해져 있지 않나요?

파이썬이 처음에 개발 될 당시에는 리눅스/유닉스에서 사용하는 스크립트 언어 기반이었기 때문에 프로그램의 시작점이 따로 정해져 있지 않았습니다. 보통 리눅스/유닉스의 스크립트 파일은 파일 한 개로 이루어진 경우가 많은데, 이 스크립트 파일 자체가 하나의 프로그램이다 보니 시작점이 따로 필요하지 않습니다. 하지만 C 언어나 자바같은 언어는 처음 만들어질 때부터 소스 파일을 여러 개 사용했기 때문에 여러 소스 파일의 함수들 중에서도 시작 함수(main)를 따로 정해 놓았습니다.

공통 세션 Linux & Terminal

현대 개발자의 필수품!
리눅스는 OS
그곳에서 명형어를 전달하는 수단이 Terminal

linux가 무엇인지 이해한다.
✔️ 리눅스의 기본 명령어들과 파일시스템 구조를 이해한다.
✔️ 환경변수에 대해 이해한다.
✔️ Shell이란 무엇인지 이해한다.
✔️ . 파일이 무엇인지 알고 있다.
✔️ 리눅스 명령어에 대해 알고 있다.

위 5개만 정확히 알고 넘어가도 오늘 Linux & Terminal TIL은 충분!!

라이너스 토발즈가 Unix기반 운영체제로 리눅스를 만듬

오픈소스! (무료!)

서버는 리눅스 기반! (구글에서 배포하는 안드로이드 역시 리눅스의 한 갈래)

서버가 안정적이고, 유연하며, 무료!!

원래 CLI (command Line Interface) 기반 (사용자들을 위해 GUI (Graphic User Interface) 기능 추가

  • 🚨 서버(로컬 서버, AWS 등에 설치된 인스턴스 등)에 설치된 리눅스 환경을 사용할 수 있음 (매우 중요!)
    • 예를 들어 우리가 만든 프로젝트를 AWS EC2 등을 통해 배포하려고 하는데 해당 서버에는 순수한 우분투 외에는 아무 것도 깔려 있지 않은 상태. 만약 git을 GUI를 통해서만 사용할 줄 안다면 여러가지 프로그램과 환경설정, 그 프로그램들의 확장 프로그램을 모두 설치한 후에야 사용 가능. (이 외에 리눅스 기반 가상 컨테이너를 사용하는 기술들 ⇒ ex. Docker🐳, Kubernetes📦 ⇒ 윈도우즈와의 호환은 아직 불완전한 상태)
  • 서버의 다양한 동작들을 매뉴얼하게 조작할 수 없음. 쉘 스크립트를 사용한 파이핑, 스케줄링, 유저 그룹 및 파일/폴더에 대한 권한 설정 등.

핵심 개념

FHS( Filesystem Hierarchy Standard)

각 폴더별 특징 (지금 외우지 않아도 된다 쓰면서 익숙해질 것) (필요할 때 다시 여기와서 복습)

  • /
    • 루트 폴더. 최상위 경로. / 기호로 접근할 수 잇다.
  • /bin & /sbin
    • 윈도우 : C드라이브/windows/system32 폴더
    • Binary의 약자. OS의 최소한의 구동을 위해 필요한 프로그램이 들어있는 폴더. cat, chmod, chown, cp, date, echo, kill, ln, ls, mkdir, etx 와 같은 기초적인 프로그램들이 포함.
    • sbin 폴더는 bin과 유사하지만 오직 루트유저 전용 프로그램 포함.
  • /boot
    • 윈도우 : C드라이브/windows/system32 폴더, boot.ini
    • 부트로더 같이 시스템 부팅에 필요한 파일들이 위치.
  • /home
    • 윈도우 : C드라이브/Users/사용자명 ⇒ 바탕 화면, 다운로드, 내 문서
    • 유저의 공간. 가장 빈번하게 사용하게 되는 경로. Home 디렉토리 이외의 다른 디렉토리 들은 주로 system directory 라고 하는데, 즉 리눅스의 운영과 관리에 관련한 파일들이 존재하는 디렉토리들. ~ 기호로 접근할 수 있다.
  • /usr
    • 윈도우 : C드라이브/Users/사용자1
    • user의 약자. 각 유저 이름에 해당하는 폴더이름이 존재. 각 폴더마다 bin, sbin, shared, lib과같이 각 유저들이 사용할 수 있는 폴더가 생성되어 있음. 각각의 유저별로 다른 파티션으로 존재하기 때문에 다른 사용자들이 사용할 수 있도록 마운트할 수 있지만 이 경우 수정할 수는 없음.
  • /etc
    • etc 폴더에는 시스템 전체에서 사용하는 설정 정보 등 엑스트라 데이터들이 저장됨.
  • /cdrom
    • 윈도우 : E, F 드라이브
    • cdrom을 위한 마운팅 포인트. 잘 사용되지 않음.
  • /media & /mnt
    • Media는 OS에서 자동으로 마운팅해주는 포인트, Mnt는 사용자가 직접 마운트하는 경로로 사용됨. 예를 들어 컴퓨터에 USB꽂아 OS에 자동으로 마운팅된다면 주로 Media 폴더, 외부에 있는 디스크등을 직접 명령어를 통해 마운트한다면 Mnt 디렉토리에 위치하게 됨.
  • /dev
    • device의 약자. 모든 것은 파일이다 라는 모토에 맞게 키보드, 마우스, 프린터등과같은 디바이스들은 파일 또는 디렉토리의 형태로 dev 폴더 안에 존재. 읽기 쓰기도 가능하며 디렉토리 어디서든 접근 가능.

PATH

  • / : root 디렉토리

  • ~ : home 디렉토리

  • 절대 경로 : Absolute path는 이름 그대로 절대적 경로. 경로를 표현하는 방식이 root 디렉토리 부터 시작한다는 점에서 "완전한"의 의미에 더욱 가까움. (ex. /home/eun/bin)

  • 상대 경로 : Relative path. 현재 자신의 위치를 기반으로 움직이는 경로. (ex. cd ..)

    • . : 현재 경로
    • .. : 상위 경로
  • 환경 변수 : 경로에 대한 변수라고 생각하면 쉽다

  • 여러분이 프로그램을 개발해서 배포하려는 상황. 대부분 C드라이브에 윈도우가 설치되어 있을 것으로 가정하고, C → program files/프로젝트 명으로 설치하도록 설정. 만약 사용자의 OS가 설치된 드라이브가 D라면 설치에 실패할 것. 이 경우 C:\program files는 변수처럼 처리되어야 한다.

  • echo $변수명 : echo 뒤에 나오는 문자열은 화면에 출력된다. echo $PATH의 실행결과는 다음과 같다. 즉, 경로에 대한 정보가 직렬화 된 문자열로 저장되어 있는 것. 명령어를 사용할 때 경로가 지정되어 있지 않으면 shell이 $PATH에서 실행하고자 하는 프로그램이 존재하는지 여부를 하나씩 체크한다. 있으면 실행한다. 각 경로는 : 으로 구분된다.

    /Library/Frameworks/Python.framework/Versions/3.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
  • 실제 ls 명령어는 /bin 디렉토리 안에 위치해 있다. whereis ls 를 입력해보자. 해당 명령어가 위치해 있는 경로를 별도로 지정해주지 않더라도 어디서든 사용이 가능한 이유 역시 환경 변수 덕분이다.

Configs

  • 리눅스에서는 주로 파일을 통하여 설정(config). (ex. .bashrc, .zshrc)

  • shell 설정 파일을 비롯한 많은 설정 파일들이 대부분 유저의 home(~) 디렉토리에 있음.

  • . 으로 시작하는 파일 및 디렉토리는 숨김파일로 간주(dot file)

  • lsa 옵션을(all) 주어야지만 볼 수 있음.

  • alias(별칭, "다른 방법으로") : 일종의 사용자 지정 단축 명령어 (.zshrc, .bashrc 등에 등록)

    alias myip="ipconfig getiadder en0" # macOS
    alias myip="hostname -I" # ubuntu

Shell Commands

Django 관계형 데이터

raw data

물리적,

과제 한것,

profile
🇰🇷🇺🇸 #Back-End Engineer

0개의 댓글