본문 바로가기

Python

I&O, Setting & Exception & Logging, Web

<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의 데이터 객체 표현 방식

    - 자료 구조 양식을 문자열로 표현

    - 간결하게 표현되어 사람과 컴퓨터 모두 읽기 편함

    - 코드에서 불러오기 쉽고 파일 크기 역시 작은 편

    - 최근 각광받는 자료구조 형식

 

Dictionary와 유사한 형태

 

Reading JSON

  • json 라이브러리로 읽기 쓰기 가능

test.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 읽어 보기

test.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

 

JSON과 유사한 표기 방식이 다름

  • E-mail 양식에서 개념을 얻은 데이터 직렬화 양식

    - [YAML은 마크업 언어가 아니다]라는 재귀적 이름

    - 들여 쓰기로 구조체를 구분

    - [Key: Value] 형식의 해시 및 [-item] 형식의 리스트 사용

    - 공백 없는 텍스트는 따옴표 없이 사용 가능

    - .yaml 혹은 .yml 확장자

  • Python에서는 pyyaml 라이브러리를 사용

 

Reading YAML

  • pyyaml로 YAML 읽어 보기

test.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 이상 출력

 

 

test.log

 

 

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 기록')

test.log

 

 


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