Path (경로) : 자원의 위치, 파일 시스템에서는 파일이나 디렉토리가 있는 위치의 경로
경로를 표시하는 방법 2가지 : 절대경로, 상대경로
절대경로 : 시작 경로부터 자원이 있는 위치까지 표현, 절대적인 경로(일정하다)
시작경로 : Root Path
- windows : c:, d:
- Uinx, Linux : /
항상 Root 경로부터 시작 -> 윈도우 -> c: or d: 유닉스나 리눅스 -> /
ex) C:\Users\Playdata\Desktop\01_Python\calculator.py
상대경로 : 현재 작업 경로를 기준으로 해서 자원의 위치 표현
시작 경로 : 현재 작업경로
구문
- . : 현재 디렉토리
- .. : 상위 디렉토리
- / : 경로 구분자, 상위경로/하위경로
항상 ./ 부터 시작한다 (현재 디렉토리에서 부터 찾아가기 때문) -> ./ 생략이 가능하다.
ex) 현재 디렉토리에서 상위 디렉토리로 나간 후 01_Python 디렉토리로 들어간다.
calculator.py 파일 -> ./../01_Python/calculator.py 또는 ../01_Python/calculator.py (./생략)
운영체제(O/S)별 경로구분자
- 윈도우즈: \ (역슬래쉬)
- 리눅스/유닉스: / (슬래쉬)
- 파이썬은 역슬래쉬와 슬래쉬 상관 없다.
# 경로를 문자열로 표시
file_path1 = "C:\\Users\\Playdata\\Desktop\\01_Python\\calculator.py" # 절대경로
file_path2 = r"C:\Users\Playdata\Desktop\01_Python\calculator.py" # r-string : escape 문자 처리를 안함
print(file_path1)
print(file_path2)
# 절대경로와 상대경로 입력 예시
file_path3 = '/src/python/a.py' # 절대경로
file_path4 = './python/a.py' # 상대경로
file_path5 = 'python/a.py' # 상대경로, 시작의 ./는 생략 가능
file_paht6 = 'calculator.py' # 상대경로 -> ./calculator.py에서 ./생략, 현재 디렉토리에 있는 calculator.py
현재 경로 -> working directory -> 현재 실행중인 프로그램의 위치
주피터노트북 -> 노트북파일의 위치, script 파일 실행 -> script 파일의 위치
# 현재 working dircetory 조회
import os # os 내장함수 등록
cwd = os.getcwd() # getcwd 실행중인 파일 위치 조회 함수
print(type(cwd), cwd)
f_path = './calculator.py' # ./ 생략 가능
# 파일이 있는지 여부 조회
os.path.isfile(f_path) # f_path에 파일이 있는지 여부
# 현재 working directory를 변경
os.chdir(r"c:\Users") # ./ -> c:\Users 로 변경
print(os.getcwd())
os.path.isfile(f_path) # 디렉토리 변경 후 f_path에 파일이 있는지 여부
# os 모듈의 파일/디렉토리 관련 함수들
# 디렉토리 생성
try:
os.mkdir(r"c:\Users\playdata\abcd") # abcd라는 디렉토리를 c:\Users\playdata 하위에 생성
# 이미 디렉토리가 있거나, 생성하려는 디렉토리(c:\Users\playdata)가 없으면 Exception 생성
except FileExistsError: # 이미 있는 디렉토리의 경우 pass한다.
# print('')
pass
except FileNotFoundError: # 생성하려는 상위디렉토리가 없어서 발생
print('상위 디렉토리를 먼저 생성하세요.')
exist_ok = False(defalut) -> 이미 있는 디렉토리면 Exception 발생
exist_ok = True -> 디렉토리가 있으면 무시
# 상위 디렉토리가 없으면 상위디렉토리도 만들어준다.
os.makedirs(r"c:\Users\playdata\abcd", exist_ok = True)
# 디렉토리 삭제
os.rmdir(r"c:\Users\playdata\abcd") # 아까 만든 디렉토리 삭제
# 파일 삭제
os.remove(r"C:\Users\Playdata\del.file.pub") # 지정된 경로의 파일을 삭제한다.
# 경로 : 상대/절대 모두 가능
file_list = os.listdir(r"C:\Users\Playdata\Desktop\01_Python") # 지정한 디렉토리의 하위요소들의 이름 문자열을 리스트에 담아 반환
file_list # 디렉토리인지 파일인지는 알 수 없음
os.path.join("a", "b", "c", "d") # os 모듈 함수
# 경로 내부의 디렉토리와 파일 구분하기
root_path = r"C:\Users\Playdata\Desktop\01_Python"
for file in file_list:
print(file)
file_path = os.path.join(root_path, file)
if os.path.isfile(file_path):
print('File', file)
elif os.path.isdir(file_path):
print('Dir', file)
입출력(I/O) : 프로그램과 외부 자원간의 데이터를 입력받거나 출력하는 것.
- 입출력시 데이터의 흐름 -> Stream
프로그램이 외부로부터 데이터를 읽어 들이는 흐름 -> 입력 스트림,
프로그램이 외부로 데이터를 써주는 흐름 -> 출력 스트림.
IO 코딩 순서 : 파일 열기(연결) -> 데이터를 파일에 쓰기/읽기 -> 파일 닫기(연결 끊기)
파일 열기(연결)
- opne() 함수 사용 : 연결된 파일과 입출력 메소드를 제공하는 객체(Stream)를 리턴
구문 : open(file, mode='r', encoding=None)
함수 주요 매개변수
file : 연결할 파일 경로
mode : 열기 모드, mode는 목적, 데이터종류를 조합한 문자열을 사용한다.
목적 r 읽기 모드-목적의 기본 모드
w 새로 쓰기 모드
a 이어 쓰기 모드
x 새로 쓰기모드-연결하려는 파일이 있으면 Exception발생
데이터종류 b binary 모드
t Text모드-text데이터 입출력시 사용 (defalut)
encoding : 텍스트 파일일 경우 인코딩 방식, None 또는 생략하면 os 기본 encoding방식을 따른다.
- Windows: cp949/euckr
- Linux, Unix: utf-8
문자 -> 이진 : 인코딩, 이진 -> 문자 : 디코딩
출력 메소드
write(출력할 Data) : 연결된 파일에 출력할 Data 출력한다.
writelines(문자열을 가진 컬렉션) : 리스트, 튜플, 집합이 원소로 가진 문자열들을 한번에 출력한다.
- text 출력일 경우에만 사용가능.
- 원소에 문자열 이외의 타입의 값이 있을 경우 TypeError 발생
import os
os.chdir(r"C:\Users\Playdata\Desktop\01_Python") # 디렉토리 변경
print(os.getcwd()) # 현재 작업중인 디렉토리 확인
# 출력할 파일들을 저장할 디렉토리를 생성
os.makedirs("files", exist_ok = True)
# 1. 출력할 파일과 연결
fw = open("files/test.txt", # 연결할 파일의 경로
mode = 'wt', # w : 출력(파일이 없으면 만들어서 연결, 있으면 연결후에 파일내용을 삭제), t : text -> 생략가능.
encoding = "utf-8" # 문자열 인코딩 방식. 생략 : os의 기본 인코딩방식(win -> cp949, mac -> utf-8)
)
print(type(fw))
# 2. 출력(output) 작업
fw.write("안녕하세요. \n")
fw.write("반갑습니다. \n")
fw.write("Hello world")
# 3. 파일과 연결 닫기
fw.close()
# 선택한 경로에 있는 test.txt 파일 확인
# 1. 출력할 파일과 연결
fw = open("files/test2.txt", # 연결할 파일의 경로
mode = 'at', # a : 출력(이어쓰기, 기존 내용을 지우지 않으며 여러번 실행 가능하다.), t : text -> 생략가능.
# mode = 'xt' x = 파일이 있으면 기존 파일이 지워지는것을 방지한다.
encoding = "utf-8" # 문자열 인코딩 방식. 생략 : os의 기본 인코딩방식(win -> cp949, mac -> utf-8)
)
print(type(fw))
# 2. 출력(output) 작업
fw.write("안녕하세요. \n")
fw.write("반갑습니다. \n")
fw.write("Hello world")
# 3. 파일과 연결 닫기
fw.close()
# 선택한 경로에 있는 test.txt 파일 확인
# 연결
fw = open("files/test4.txt", "wt", encoding = "utf-8")
txt = {"aaaaa", "11111", "가가가가", "333333", "0000000"}
# 출력
# for i in txt:
# fw.write(i)
fw.writelines(txt) # for문의 결과와 동일하게 txt파일이 만들어진다. 엔터를 자동으로 넣어주지는 않는다.
# 연결닫기
fw.close()
# TextIOWrapper (fw)의 속성 조회 -> 연결 Stream 생성
print(fw.mode, fw.encoding, fw.name)
print("연결 여부를 확인 : ", fw.closed)
"연결닫힘" if fw.closed else "연결중임"
# 연결중이라면 연결중인 파일은 다른 프로그램에서의 조작이 제한된다.
입력 메소드
read() : 문자열(text mode), bytes(binary mode)
- 연결된 파일의 내용을 한번에 모두 읽어 들인다.
readline() : 문자열(text mode), bytes(binary mode)
- 한 줄만 읽는다.
- text 입력일 경우만 사용가능
- 읽은 라인이 없으면 빈문자열을 리턴한다.
readlines() : 리스트
- 한번에 다 읽은 뒤 각각의 라인을 리스트에 원소로 담아 반환한다.
Input Stream (TextIOWrapper, BufferedReader)는 Iterable 타입
- for문을 이용한 라인단위 순차 조회할 수 있다.
# 읽기
# 1. 연결
fr = open("files/test.txt", mode = 'rt', encoding = 'utf-8' # r : defalut, t : defalut -> rt일 경우 mode = rt 생략가능
) # encoding defalut -> cp949, utf-8로 바꿔야 한다.
# 입력할 때의 인코딩 방식과 읽을 때의 인코딩 방식이 같아야 한다.
# 2. 읽기
read_txt = fr.read() # read() -> 전체를 한번에 읽어준다.
print(read_txt)
# 3. 연결 닫기
fr.close()
# 읽기
# 1. 연결
fr = open("files/test.txt", mode = 'rt', encoding = 'utf-8' # r : defalut, t : defalut -> rt일 경우 mode = rt 생략가능
) # encoding defalut -> cp949, utf-8로 바꿔야 한다.
# 입력할 때의 인코딩 방식과 읽을 때의 인코딩 방식이 같아야 한다.
# 2. 읽기
# read_txt = fr.readline() # readline() -> 한줄만 읽는다. ...........\n(엔터 까지만 읽는다.)
# print(read_txt)
# read_txt = fr.readline() # 한번더 readline 할 시에, 어디까지 읽은지 알기에 이어서 읽는다. (더이상 읽을 것이 없는 경우 None 반환)
# print(read_txt)
read_txt = fr.readline() # 한줄씩 읽겠다.
while read_txt:
print(read_txt, end = '')
read_txt = fr.readline()
# 3. 연결 닫기
fr.close()
fr = open("files/test.txt", mode = 'rt', encoding = 'utf-8')
txt_list = fr.readlines()
fr.close()
print(txt_list)
# enumerate 활용하여 순서와 텍스트
for line_no, txt in enumerate(txt_list, start = 1):
print(f"{line_no} {txt.strip()}")
fr = open("files/test.txt", mode = 'rt', encoding = 'utf-8')
# Text 입력 Stream (TextIOWrapper) --> Iterable 타입 -> for in문으로 사용가능
# --> 한번 반복할 때마다 한줄 읽은 것을 반환
for ln, txt in enumerate(fr, start = 1):
print(ln, txt.strip())
with block : 파일의 입출력 작업이 끝나면 close()를 통해 매번 닫아야 하지만 with block을 사용하면 block을 벗어나면 자동으로 연결을 닫아준다. 그래서 close() 코드를 생략할 수 있다.
with open("files/test.txt", "rt", encoding="utf-8") as fr:
txt = fr.read()
# print(10/0)
# with block을 빠져 나옴. => 자동을 stream이 close 된다.
print(txt)
print(f"fr 연결여부: {fr.closed}") # close()없이 자동으로 close된것을 확인할 수 있다.'Data_Analysis_Track_33 > Python' 카테고리의 다른 글
| Python_09(Iterable) (0) | 2023.08.25 |
|---|---|
| Python_08-2(입출력) (0) | 2023.08.25 |
| Python_07-2(Exception 발생시키기) (0) | 2023.08.24 |
| Python_07(예외처리) (0) | 2023.08.23 |
| Python_06-2(Package&Module, import) (0) | 2023.08.23 |