<I&O, Setting & Exception & Logging, Web>
11. Input & Output
12. Setting & Exception & Logging
13. Web
Input & Output
Standard Input & Standard Output
- 따로 Redirection이 없으면 콘솔 입, 출력
File Open
- Python은 File Descriptor를 열기 위하여 open 내장 함수 사용
fd = open("<파일 이름>", "<접근 모드>", encoding="utf8") # 파일 열기, Unix 인코딩 기본 인자는 utf8
fd.close() # 파일 닫기
| 접근 모드 | 설명 |
| r | 읽기 모드 - 파일을 텍스트 형태로 읽을 때 사용 |
| rb | 이진 읽기 모드 - 파일을 바이너리 형태로 읽을 때 사용 |
| w | 쓰기 모드 - 파일을 텍스트 형태로 쓸 때 사용 |
| wb | 이진 쓰기 모드 - 파일을 바이너리 형태로 쓸 때 사용 |
| a | 추가 모드 - 파일의 마지막에 새로운 텍스트를 추가할 때 사용 |
File Read
- Read 메소드로 파일 읽기 가능
fd = open('text.txt', 'r')
contents = fd.read() # 파일 전체 읽기
fd.close()
- File descriptor 닫는 것을 깜박할 때가 많음
- Context Manager 형태로 사용 (자동으로 닫아줌)
- with <ContextManager> as <Return Value>
with open('text.txt', 'r') as fd: # Context Manager
contents = fd.read() # 파일 전체 읽기
File Read Lines
- 줄 단위로 잘라서 읽기, \n가 사라지는 건 아니다.
with open('text.txt', 'r') as f:
for sentence in f: # readline() 활용도 가능
contents.append(sentence)
- 전체 읽어 줄 단위로 잘라서 반환 → readlines
with open('text.txt', 'r') as f:
contents = f.readlines() # 전체 읽기 후 줄 단위 자름
File Write
- Write 메소드로 파일 쓰기 가능
with open('text.txt', 'w') as fd:
for i in range(10):
fd.write(f"{i+1}번 째 문장\n")
- Wrtielines 메소드로 여러 줄 작성
- 줄 바꿈 문자 \n을 넣어주진 않음
with open('text.txt', 'w') as fd: # String Iterable으로 쓰기
fd.writelines(f"{i+1}번 째 줄입니다.\n" for i in range(10))
- 추가하기 모드 ("a")로 파일 뒤에 덧 붙이기 가능
i = 10
with open('text.txt', 'a') as fd: # Append 모드
fd.write('내용을 추가합니다.\n')
fd.wrtielines(f"{i+1}번째 줄입니다.\n") for i in range(i, i + 10)
Directory
- os 라이브러리로 플랫폼 독립적인 폴더 생성 가능
- Python에선 Windows, Unix 모두 '/'로 폴더를 나타냄
- path 라이브러리로 경로 관련 연산 가능
import os
os.mkdir('test') # 폴더 하나 만들기, 이미 있으면 에러 발생!
if not os.path.isdir('test'): # 폴더가 있는지 확인
os.mkdir('test') # 폴더가 아니거나 없으면 False
# 하위 폴더 한번에 만들기, exist_ok 옵션으로 이미 있으면 무시할지 확인
os. makedirs('test/a/b/c', exist_ok=True)
Listing Directory
- listdir 함수로 폴더 내 파일/하위 폴더 검색
import os
print(*[entry for entry in os.listdir('test')]) # * 리스트 Unpacking
# a.txt b.txt
- glob 라이브러리로 유닉스 스타일 경로명 패턴 확장 적용
- Linux 환경에서 사용 가능
import glob
print(*[entry for entry in glob.glob('test/*.txt')])
# test/a.txt test/b.txt
Pickle
- Python 객체를 그대로 저장하고 싶을 때 사용
- 객체를 직렬화(serialize)하여 파일로 저장
import pickle # pickle 라이브러리 import
seq = [[i * j for j in range(100)] for i in range(100)] # 저장하고 싶은 객체
with open('test.pkl', 'wb') as fd:
pickle.dump(seq, fd) # pickle 저장
del seq # 객체 삭제
with open('test.pkl', 'rb') as fd:
seq = pickle.load()fd # pickle 불러오기
print(seq[10][9]) # 개체 접근 가능
| 장점 | 단점 |
| - 쓰기 쉽다 - 파이썬 객체를 그대로 저장 |
- Python에서만 읽을 수 있다. - 보안 문제가 있다 → 신뢰할 수 있는 개체만 불러올 것! |
Class Pickling
- Class 객체를 직렬 하기 위해선 해당 클래스가 직렬화 가능 필요
- 모든 속성이 직렬화 가능 필요
- 저장된 객체 pickle을 로드하고 싶다면 미리 해당 클래스 선언 필요
- 해당 클래스 정보가 없다면 역직렬화 불가능
→ del Class 시, 에러 발생
Comma Separte Values
- 표 데이터를 프로그램에 상관없이 쓰기 위한 데이터 형식
- 필드를 쉼표(,)로 구분한 텍스트 파일
- 탭(TSV), 공백(SSV) 등으로 구분하기도 함
- 통칭하여 Character Separated Values (CSV)라 지칭

Reading CSV
import csv
with open('test.csv', 'r') as fd:
reader = csv.reader(fd, # File Descriptor, 필수
delimiter=',', # 구분자, defaul: ,
quotechar='"', # 텍스트 감싸기 문자, default: "
quoting=csv.QUOTE_MINIMAL # Parsing 방식, default: 최소 길이
)
for entry in reader: # 한 줄씩 순환
print(entry) # Row를 List 형태로 출력
Writing CSV
- csv 라이브러리로 쉽게 csv 읽기 쓰기 가능
import csv
with open('test.csv', 'ㅈ') as fd:
writer = csv.writer(fd, # File Descriptor, 필수
delimiter=',', # 구분자, defaul: ,
quotechar='"', # 텍스트 감싸기 문자, default: "
quoting=csv.QUOTE_MINIMAL # Parsing 방식, default: 최소 길이
)
writer.writerow(['id', 'label']) # 한 줄 쓰기
writer.writerows([i, f'label_{i}'] for i in range(10)) # 여러 줄 쓰기
JavaScript Object Notation
- 웹 언어인 Javascript의 데이터 객체 표현 방식
- 자료 구조 양식을 문자열로 표현
- 간결하게 표현되어 사람과 컴퓨터 모두 읽기 편함
- 코드에서 불러오기 쉽고 파일 크기 역시 작은 편
- 최근 각광받는 자료구조 형식

Reading JSON
- json 라이브러리로 읽기 쓰기 가능

import json
with open('test.json', 'r') as fd:
data = json.load(fd)
print(data['hobbies']) # ['reading', 'cinema', {'sports': ['volley-ball', 'snowboard']}]
print(data['hobies'][2]['sports'][0]) # volley-ball
Writing JSON
- json 라이브러리로 읽기 쓰기 가능
- 직렬화 가능 객체(원시 Type, 자료 구조) 이 외에는 Decoder 작성 필요
import json
obj = {
"ID": None,
"bool": False,
"hobbies": {
"sports": [
"snowboard",
"volley-ball"
]
}
}
with open('test.json', 'w') as fd:
json.dump(obj, fd) # json 쓰기
eXtensible Markup Language

- 데이터 구조와 의미를 설명하는 Tag를 활용한 언어
- <Tag>와 </Tag> 사이에 값 표시
- 문자열로 처리
- <태그 속성=값> 형태로 태그에 속성 부여
- HTML은 웹 페이지 표시를 위한 XML
- 정규표현식으로 parsing 가능
→ HTML 파일을 읽어 웹 크롤러 제작 가능
Beautiful Soup
- Python 기본 XML Parser는 다소 불편
- 일반적으로 XML, HTML 파싱을 위해 외부 라이브러리 사용
- Beautiful Soup, xmltodict, ....
- Beautiful Soup
- 가장 많이 쓰이는 parser 중 하나
- HTML, XML 등 Markup 언어 Scraping을 위한 도구
- 속도는 다소 느리나 간편하게 사용
Reading XML
- Beuatiful Soup로 XML 읽어 보기

from bs4 import BeautifulSoup # BeautifulSoup 객체 들고 오기
with open('test.xml', 'r') as fd:
soup = BeautifulSoup(
fd.read(), # Parsing 할 문자열
'html.parser' # 사용할 parser
)
to tag = soup.find(name='to') # 문서 전체에서 'to' 태그 찾기
print(to_tag.string) # 'to' 태그 내 문자열 출력
for cite_tag in soup.findAll(name='cite') # 'cite' 태그 모두 찾기
print(cite_tag.string)
cites_tag = soup.find(name='cites') # 'cites' 태그 찾기
print(cites_tag.attrs) # 'cites' 태그의 모든 속성
print(cites_tag['attr']) # 'attr' 속성 값 참조
cites_tag = soup.find(attrs={'attr': 'name'}) # 속성으로 태그 찾기
for cite_tag in cites_tag.find_all(name='cite'): # 태그 내 검색
print(cite_tag.string)
Yaml Ain`t Markup Language

- E-mail 양식에서 개념을 얻은 데이터 직렬화 양식
- [YAML은 마크업 언어가 아니다]라는 재귀적 이름
- 들여 쓰기로 구조체를 구분
- [Key: Value] 형식의 해시 및 [-item] 형식의 리스트 사용
- 공백 없는 텍스트는 따옴표 없이 사용 가능
- .yaml 혹은 .yml 확장자
- Python에서는 pyyaml 라이브러리를 사용
Reading YAML
- pyyaml로 YAML 읽어 보기

import yaml
import pprint # 예쁘게 출력하기 용
with open('test.yaml') as fd:
data = yaml.load(fd, Loader=yaml.FullLoader)
pprint.print(data)
'''{'calling-birds': ['huey', 'dewey', 'lcuie', 'fred'],
'doe': 'a deer, a female deer',
'french-hens': 3,
'pi': 3.14159,
'ray': 'a drop of golden sun',
'xmas': True,
'xmas-fifth-day': {'calling-birds': 'four',
'french-hens': 3,
'golden-rings': 5,
'partridges': {'count': 1, 'location': 'a pear tree'},
'turtle-doves': 'two'}}'''
Setting & Exception & Logging
프로그램의 설정 값
- 실행할 때마다 필요한 설정 값
- 딥러닝 학습 횟수(Epoch)
- 학습 계수(Learning rate)
→ Command Line Argument(명령행 인자)로 입력
- 한번 설정하면 수정을 잘 안 하는 설정 값
- 학습 자료 폴더 위치
- 웹 서버의 Listening Port
→ 설정 파일에서 불러들이기 (txt, YAML, ConfigParser)
명령행 인자 (Command Line Argument)
- Console 창에서 프로그램 실행 시 프로그램에 넘겨주는 인자 값
- Command-line Interface (CLI)에서 흔히 쓰이는 방식
- Python에서 sys 라이브러리의 argv 속성으로 접근
- 공백 기준으로 잘라져 문자열 형태로 입력
argparser
- argparser 라이브러리로 명령행 인자 쉽게 관리 가능
- 인자 flag를 설정 가능하여 flag 별 입력 가능 (긴 flag, 짧은 flag 활용)
- 기본값 설정 가능
- Tpye 설정 가능 (문자열에서 변환)
- Help 제공하여 사용자 편의 향상
- 이 외 명령 줄 인자와 관련된 여러 도구 포함
예외 처리 (Exception Handling)
- 예외가 발생할 경우 대응 조치 필요
- 불어올 파일이 없는 경우 → 파일이 없음을 사용자에게 알림
- 서버와 연결이 끊김 → 다른 서버로 Redirection
- 예외가 발생할 수 있는 코드 → (특정 예외 발생 시) 대응 코드 → 계속 진행
try:
<예외 발생 가능 코드>
except <예외 클래스>:
<대응 코드>
내장 예외 (Built-in Exceptions)
- 기본 정의된 예외 클래스
| 예외 이름 (Exception Class) |
설명 | 발생 가능 예시 |
| IndexError | List의 Index 범위를 넘어감 | list[I 0 I] |
| NameError | 존재하지 않는 변수를 호출 | not_exist + I |
| ZeroDivisionError | 0으로 숫자를 나눔 | I 0 / 0 |
| ValueError | 변환할 수 없는 문자열/숫자를 변환 | float('abc') |
| FileNotFoundError | 존재하지 않는 파일 호출 | open('not_exist.txt', 'r') |
- 이 외에도 많은 내장 예외 존재
Exception Class
- Python 예외는 모두 BaseException 상속
- 대부분 try로 최대 Exception 단 까지만 잡음
- Exception Class를 상속하여 새로운 예외 생성 가능

Raising & Referencing Exceptions
- Raise 구문으로 예외 발생
- raise <예외 객체>
- As 구문으로 잡힌 에러를 참조 가능
- except <예외 클래스> as <예외 객체>
try:
while True:
value = input('A B C 중 하나를 입력하세요: ')
if len(value) == 1 and value not in 'ABC':
raise ValueError('잘못된 입력입니다. 종료합니다.') # 예외 발생
print('선택된 옵션: ', value)
except ValueError as e: # as 이하 구문으로 예외 객체 들고 오기 가능
print(e)
Assertion
- 조건을 확인하여 참이 아닐 시 AsserError 발생
- assert <조건>
- assert <조건>, <에러 메시지>
- 에러 메시지가 없을 경우 빈칸으로 처리
try:
print(add_int(10))
print(add_int('str'))
except AssertionError as e:
print(e)
Post-error Processing
| 아무 구문 없음 | else 구문 | finally 구문 | |
| 예제 코드 | try: functions() except SomeError as e: print(e, '예외 발생') print('예외 이후') |
try: functions() except SomeError as e: print(e, '예외 발생') else: print('예외 이후') |
try: functions() except SomeError as e: print(e, '예외 발생') finally: print('예외 이후') |
| 진행 방식 | 일반 진행 | 예외가 없을 경우 진행 | 모든 경우 진행 |
| 예외 발생이 없을 경우 | '예외 이후' 출력 | '예외 이후' 출력 | '예외 이후' 출력 |
| SomeError 발생 | '예외 발생' 출력 '예외 이후' 출력 |
'예외 발생' 출력 | '예외 발생' 출력 '예외 이후' 출력 |
| 다른 예외 발생 | 프로그램 비정상 종료 | 프로그램 비정상 종료 | '예외 이후' 출력 프로그램 비정상 종료 |
Logging
- 프로그램이 일어나는 동안 발생했던 정보를 기록
- 결과 처리, 유저 접근, 예외 발생... 등
- 기록된 로그 분석을 통한 디버깅 & 유저 패턴 파악
- 기록 용도에 따른 차이
- 용도에 따라 출력 형식 및 필터링 필요
Logging Module
- Python 기본 Logging 모듈
- 상황에 따라 다른 Level의 로그 출력
- Level: DEBUG < INFO < WARNING < ERROR < Critical
Logging Level
| Level | 설명 | 예시 |
| DEBUG | 상세한 정보, 보통 문제를 진단할 때만 사용 | - 변수 A에 값 대입 - 함수 F 호출 |
| INFO | - 프로그램 정상 작동 중에 발생하는 이벤트 보고 - 상태 모니터링이나 결함 조사 |
- 서버 시작 - 사용자 User가 서버 접속 |
| WARNING | - 예상치 못한 일이 발생하거나 가까운 미래에 발생할 문제에 대한 경고 - 대처할 수 있는 상황이지만 이벤트 주목 필요 |
- 문자열 입력 대신 숫자 입력 → 문자로 변환 뒤 진행 - 인자로 들어온 리스트 길이가 안 맞음 → 적당히 잘라서 사용 |
| ERROR | - 오류가 발생하였으나 프로그램은 동작 가능 - 프로그램 일부 기능을 수행하지 못함 |
- 파일을 읽으려니 파일이 없음 → 사용자에게 알림 - 외부 서버와 연결이 불가능 → 사용자에게 대체 서버 요청 |
| CRITICAL | - 심각한 오류 발생 - 프로그램 자체가 계속 실행되지 않을 수 있음 |
- 중요 파일이 없음 - 사용자가 강제 종료 |
Root Logging
- 기본 설정된 로깅
- Basic config로 간단하게 설정 가능
- 로그를 기록할 파일 이름
- 로그 레벨을 설정하여 특정 레벨 이상 출력
- 기본 설정
- 표준 에러 출력
- WARNING 이상 출력

Logger Management
- 새로운 Logger 생성
- getLogger로 새로운 이름의 Logger 생성
- 이름이 같은 Logger가 존재할 경우 해당 객체를 들고 옴
- 따로 설정이 되어 있지 않을 경우 Root의 설정을 상속함
import logging
logging.basicConfig( # Root 로깅 설정
filename='test.log', # 기록할 파일
)
# logger = logging.getLogger('main') # 새로운 logger 생성
logger = logging.getLogger(__name__) # 일반적으로 모듈 별로 이름을 만듦
logger.setLevel(logging.INFO) # 새 logger의 레벨 설정
logging.info('Root에 info 기록') # Root에 기록
logging.warning('Root에 Warning 기록')
logger.info('메인에서 info 기록') # 새로 만든 logger에 기록
logeer.warning('메인에서 warning 기록')

Web
HTML
- XML 형태로 웹 페이지의 구조를 표현
- Beautiful Soup 등 XML parser로 해석 가능
- 다운로드한 HTML 파일을 웹 브라우저가 해석 & 화면 표시
- F12를 눌러 개발자 모드 표시
<!doctypehtml>
<html>
<head>
<title>Hello HTML</title>
</head>
<body>
<p>Hello Wolrd!</p>
</body>
</html>
Requests
- 웹페이지를 읽기 위해서 일반적으로 Requests 라이브러리 사용
import requests
URL = 'https://www.naver.com'
response = requests.get(URL) # GET으로 접근
print(response.status_code) # 결과 코드, 200은 정상, 404는 웹페이지 연결 X, 500은 웹서버 내부 오류
print(response.text) # 응답, 웹서버의 경우 HTML 코드
Crawling
- 오늘자 네이버 스포츠 뉴스 기사 제목 크롤링하기
import Requests
from bs4 import BeautifulSoup
URL = 'https://sports.news.naver.com/index' # 네이버 스포츠 뉴스
response = requests.get(URL)
soup = BeautifulSoup( # HTML Parsing
response.text,
'html.parser'
)
headline = soup.find(name='ul', attrs={'class': today list'})
for title in headline.find_all(name='strong', attrs={'class': 'title'}):
print(title.string)
'Python' 카테고리의 다른 글
| Colab Runtime 유지 (0) | 2022.08.01 |
|---|---|
| Advanced Data Structure & String (0) | 2022.04.28 |
| OOP, Module & Package (0) | 2022.04.27 |
| Python Programming (0) | 2022.04.26 |
| Python Basic (0) | 2022.04.25 |