2023-07-14
2023.07.11 - [LG 헬로비전 DX DATA SCHOOL/Python] - 파이썬 Data Type 및 처리
파이썬 Data Type 및 처리
2023-07-11/ ~ /0713 2023.07.11 - [LG 헬로비전 DX DATA SCHOOL/Python] - 객체 지향 프로그래밍 (OOP) 객체 지향 프로그래밍 (OOP) 2023-07-11 오늘은 저번 시간에 이어서 파이썬에서의 객체지향 프로그래밍에 대해서
dxdata.tistory.com
이전 글입니다
예외 처리의 간단한 설명도 같이 있습니다!
저번에 이어서 예외처리에 대해서 알아보겠습니다!
1. 예외 처리
1.1) 예외
- 문법적인 오류는 없어서 실행은 되지만 실행 도중 발생한 예기치 않은 상황으로 인해 프로그램이 중단되는 현상
1.2) 예외처리
- 예외가 발생했을 때 비정상 종료를 하지 않고 정상적인 수행을 하도록 처리하는 것
1.3) 기본형식
try :
예외가 발생할 가능성이 있는 구문
except :
예외가 발생했을 때 수행할 내용
1.4) 예외를 종류 별로 처리하기
- except 다음에 예외 클래스 이름을 기재한 후 처리하는 코드를 작성하면 예외 클래스 이름에 해당하는 예외가 발생했을 때 구문을 수행합니다.
- except 는 여러 개 작성이 가능한데, if~ elif 처럼 동작 (예외 하나씩 수행)
ar = [10, 20, 30]
su = int(input("나눌 수를 입력하세요:"))
i = 0
#while i <= len(ar) : # len이라는 함수로 고정값을 찾아오기 보단 미리 수를 받아오는게 좋다.
j = len(ar)
try :
while i < j :
print(ar[i] / su)
i = i + 1
#나눗셈의 return 값은 기본적으로 float!!!!
except ValueError:
print("잘못된 값을 입력했어요")
except ZeroDivisionError :
print("0으로 나눌 수는 없습니다")
print(type(ar[1]/su))
1.5) 예외 내용을 받아서 처리하기
except 예외 클래스 이름 as 변수명 :
- 위의 경우에는 예외 내용을 변수에 대입하게 됩니다.
- 변수를 출력하면 어떤 예외가 발생했는지 알 수 있습니다.
ar = [10, 20, 30]
su = int(input("나눌 수를 입력하세요:"))
i = 0
#while i <= len(ar) : # len이라는 함수로 고정값을 찾아오기 보단 미리 수를 받아오는게 좋다.
j = len(ar)
try :
while i < j :
print(ar[i] / su)
i = i + 1
#나눗셈의 return 값은 기본적으로 float!!!!
except ValueError as e : #as e를 추가하고 밑에 print!
print("잘못된 값을 입력했어요")
print(e)
except ZeroDivisionError as e:
print("0으로 나눌 수는 없습니다")
print(e)
1.6) 예외 클래스 계층
https://docs.python.org/3/library/exceptions.html
Built-in Exceptions
In Python, all exceptions must be instances of a class that derives from BaseException. In a try statement with an except clause that mentions a particular class, that clause also handles any excep...
docs.python.org
들어가서! 확인이 가능합니다.
1.7) except 뒤에 추가할 수 있는 절
- else 절 : 예외가 발생하지 않고 정상적으로 처리가 수행된 경우 수행할 내용, 정상적인 처리 다음에 수행할 내용을 작성
- finally 절 : 예외 발생 여부에 상관없이 수행할 내용, 이 절에는 외부 자원에 대한 연결을 해제하는 문장을 주로 작성
- else 와 finally를 같이 사용하고자 하는 경우에는 else를 먼저 작성해야 합니다. finally는 예외 처리 구문이 종료됨을 의미합니다.
1.8) 강제로 예외를 발생시키기
- raise Exception(메시지) : 현재 함수 내에서 예외를 처리합니다.
- raise : 호출하는 함수로 예외를 던지기(예외를 발생시켜버림. 다른 언어들은 throw/throws, 단 Oracle은 똑같이 raise로 예외를 발생 - 데이터 베이스에서 예외는 처리를 안해주겠다라는 의미)
9)assertion(단언)
- 강제로 프로그램을 중단하는 것
assert 프로그램이 중단되지 않는 조건 [,에러메세지(생략 가능)]
ar = [10, 20, 30]
su = int(input("나눌 수를 입력하세요:"))
i = 0
#while i <= len(ar) : # len이라는 함수로 고정값을 찾아오기 보단 미리 수를 받아오는게 좋다.
j = len(ar)
try :
while i < j :
if su == 1 :
raise ValueError("강제로 예외 발생") #raise 이용 예외처릐
assert su != 2, 'su는 2이면 안됩니다.'
#수에 2가 입력되면 프로그램은 중단됩니다 -> assertion
print(ar[i] / su)
i = i + 1
#나눗셈의 return 값은 기본적으로 float!!!!
except ValueError as e : #as e를 추가하고 밑에 print!
print("잘못된 값을 입력했어요")
print(e)
except ZeroDivisionError as e:
print("0으로 나눌 수는 없습니다")
print(e)
else :
print("예외가 발생하지 않은 경우 수행할 내용")
finally :
print("무조건 수행하는 문장")
2. File Handling
2.1) 파일 처리 과정
- open 이라는 함수를 이용해서 운영체제에게 파일을 사용할 수 있도록 요청
- 파일이 존재하면 파일에 대한 참조를 리턴을 하고 파일이 존재하지 않으면 생성을 하던가 아니면 예외를 발생시킴.
- 파일에 대한 읽고 쓰기 작업을 함수를 이용해서 수행하면 운영체제가 작업을 수행하고 그 결과를 리턴
- close 함수를 이용해서 파일을 닫습니다.
2.2)파일 쓰기 작업
- open 함수에 2개나 3개의 매개변수를 대입해서 파일을 열기
- 첫번째 매개변수는 파일의 경로이고 두번째는 'w'이고 세번째 인코딩 방식(생략하면 시스템 인코딩 - utf-8
- 기록을 할 때는 파일 참조 변수를 이용해서 write를 호출
- \n이 포함된 컬렉션의 경우는 writelines 나 join을 이용해서 줄 단위 기록이 가능
2.3) 파일 읽기 작업
- open 함수에 1개나 2개의 매개변수를 대입해서 파일을 열기
- 첫번째 매개변수는 파일 경로
- 두번째 매개변수로 'r'을 대입할 수 있는데 생략하면 'r'
- read()를 사용하면 전체를 읽어옴
- readline()을 이용하면 줄 단위로 읽고 readlines 는 줄 단위로 읽어서 list로 리턴
- read(정수)는 정수 바이트 만큼 읽어옴
2.4)현재 작업 디렉토리 확인 및 변경
- os.getcwd() : 현재 작업 디렉토리를 리턴
- os.chdir('디렉토리') : 현재 작업 디렉토리 변경
try :
file = open('./data/test.txt', 'w', encoding = 'utf-8')
file.write("안녕") #문자열 기록
lines = ["김좌진", "김홍도", "김구"]
file.writelines(lines)
except Exception as e :
print("파일 처리 중 예외 발생", e)
- 파일을 열어서 내용을 확인 - 한글이 깨지면 open 함수에 encoding="인코딩 방식"을 추가해서 인코딩 설정을 추가해야 한다.
2.5) with 절
- 파일은 외부 자원이라서 열어서 사용하고 작업이 끝나면 close를 호출해서 해제를 해야 한다.
- close 구문은 finally에 작성해서 예외 발생 여부에 상관없이 해제를 해야 한다.
-> with open() as 파일변수 :
- 위와 같이 작성하게 되면 open의 리턴 값을 파일 변수에 저장하고 with 절이 끝나며 예외 발생 여부에 상관없이 자동으로 close()를 호출합니다.
with open('./data/test.txt', encoding = 'utf-8') as file :
#줄 단위 읽기
for line in file :
print(line)
print()
3. csv 파일
3.1) 텍스트 파일 : 문자열을 기록한 파일
- 텍스트 파일을 데이터를 저장하는 용도로 사용이 가능
- fwt : 일정한 간격을 갖는 텍스트
- tsv : 탭으로 구분한 텍스트
- csv : 쉼표로 구분한 텍스트
- 최근에는 구분자로 구분된 것은 모두 csv 라고 함
- 불변의 데이터인 경우는 csv로 제공하는 것이 일반적
3.2) csv 읽고 쓰기
- 텍스트로 읽어서 split 같은 메서드를 이용 : 문자열 내에 따옴표가 있는 경우 해석이 잘 안되는 경우가 발생
- 파이썬이 제공하는 csv 모듈을 이용하는 방법
- pandas 와 같은 외부 라이브러리를 이용하는 방법
#텍스트 파일을 읽어서 list로 변환, 마지막 데이터는 \n이 추가됩니다.
#마지막 데이터는 \n을 제거해주어야 합니다.
import re
data = []
with open('./data/test.csv', encoding='utf-8') as file :
for line in file :
ar = line.split(",")
data.append(ar)
#re.sub(r'\n','' ,data)
print(data)
- 파이썬이 제공하는 csv 모듈을 이용하는 방법
파일 객체를 csv.reader 객체에 대입하면 줄단위로 읽을 수 있는 reader 객체를 리턴하는데 이 객체를 for로 순회 하면 각 줄을 list로 변환해서 접근할 수 있도록 해준다.
읽거나 기록을 할 때
#줄단위로 읽어서 list를 만들어주는 reader객체
import csv
data = []
with open('./data/test.csv', encoding='utf-8') as file :
rdr = csv.reader(file)
for line in rdr :
data.append(line)
print(data)
csv.writer 에 파일 객체를 대입하면 csv에 기록이 가능한 객체를 생성할 수 있는데 이 객체를 가지고 writerow(list)를 호출하면 csv 파일에 기록도 가능합니다.
import csv
data = []
#w모드는 지우고 기록, r은 읽기 전용, a 는 기존 내용 뒤에 추가
with open('./data/test.csv', 'a',encoding='utf-8') as file :
wr = csv.writer(file)
wr.writerow(['이강인', '김민재', '최진철'])
wr.writerow(['이천수', '배준호', '황성주'])
print(data)
3. 바이너리 파일과 Serializable
3.1) 바이너리 파일
- 바이트 단위로 파일에 기록하고 읽기
- 바이너리 파일로 만들 때는 문자열을 직접 기록할 수 없고 encode()를 호출해서 바이트 단위로 기록.
- 바이너리 파일에서 읽은 데이터를 문자열로 변환할 때 decode()를 호출해야 합니다.
- 모드를 설정할 때 b 자를 추가
- 실제로는 텍스트 보다는 이미지 등을 저장할 때 사용
#바이트 단위로 기록하기!
with open('./data/test.bin', 'wb') as file :
file.write("안녕하세요".encode())
with open('./data/test.bin', 'rb') as file :
content = file.read()
print(content.decode())
3.2) Serializable
- 인스턴스를 파일에 기록하고 읽거나 네트워크를 통해서 전송하기 위한 작업
- 입출력은 기본적으로 byte 단위 나 character 단위로만 가능한데 사용자 정의 클래스의 인스턴스 단위로 가능하도록 하는 작업입니다.
- 이 작업을 하는 경우는 응용 프로그램을 만들고 여기서 생성된 데이터를 다른 곳에서 함부로 읽지 못하도록 하기 위해서 입니다.
- 기록
pickle(출력할 객체, 파일 객체)
읽기
pickle.load(파일 객체) : 객체 1개를 읽기
pickle.
3.3) DeSerializable
class DTO :
def __init__(self, num=0, name="이름 없음"):
self.__num = num #private 으로 만들려면 __num 삽입
self.__name = name
@property
def num(self):
return self.__num
@property
def name(self):
return self.__name #getter
@num.setter
def num(self, num):
self.__num = num
@name.setter
def name(self, name):
self.__name= name
#인스턴스를 print 함수에 대입했을 때 호출되는 메서드 : overriding
#출력을 편리하기 위해서 재정의 - 디버깅 목적
def __str__(self):
return str(self.__num) + ":" + self.__name
#파일에 기록할 데이터 생성
dto1 = DTO(1, "원빈")
dto2 = DTO(2, "아이유")
data = [dto1, dto2]
import pickle
try :
with open("./data/data.dat", "wb") as f :
#f에 data를 Serializable
pickle.dump(data, f)
except Exception as e:
print(e)
try :
with open("./data/data.dat", "rb") as f :
#f에 data를 DeSerializable
result = pickle.load(f)
for dto in result :
print(dto)
except Exception as e:
print(e)
4. 파일 압축
4.1) zip 파일 압축
- zipfile 모듈의 ZipFile 함수를 이용해서 인스턴스를 생성하고 파일 경로를 list로 만든 후 write 함수에 대입하면 압축이 됩니다.
- zipfile 해제는 extractall 함수를 호출하면 됩니다.
import zipfile
#압축할 파일 목록 생성
filelist = ["./data/data.dat", "./data/test.bin"]
#파일 목록을 순회하면서 압축
with zipfile.ZipFile('./data/test.zip', 'w') as myzip :
for temp in filelist:
myzip.write(temp)
#압축해제
zipfile.ZipFile("./data/test.zip").extractall()
4.2) tar(리눅스 압축 파일 표준) 파일 압축
- tarfile 모듈 사용
5. 로그 파일 읽기
5.1) Apache Tomcat 의 로그 파일
180.76.15.5 - - [15/Nov/2015:03:45:45 +0000] "GET / HTTP/1.1" 200 6812 (200이면 성공, 6812는 traffic)
- 공백 9개로 분리되는 데이터 -> 실제 항목은 10개
- 첫번째 항목은 접속한 IP
- 9번째 항목은 응답 코드로 200이면 성공
- 열번째 항목은 트래픽(전송량)
#로그 파일 분석 해보장!
import re
path = "./data/log.txt"
data = []
# cnt = 0
#응답 코드가 200인 데이터 세기
#ip 별 접속 회수 세기
d_list = []
f_list = []
ipCount = {}
with open(path) as f : #한글이 없으면 encoding 안해도 됨.
for line in f :
#print(line)
#읽어낸 한 줄을 공백을 기준으로 분할해서 list로 생성
a = line.split(" ")
# if a[8] == '200' :
# cnt = cnt+1
# f_list.append(a[0])
# if a[0] not in d_list :
# d_list.append(a[0])
#리스트를 이용해 ip 언급된 횟수 추출
# data.append(a)
#
# for i in d_list :
# cnt = f_list.count(i)
# print(cnt)
ipCount[a[0]] = ipCount.get((a[0]), 0)+1
for ip in ipCount :
print(ip,":", ipCount[ip])
#print(data)
#print("정상 승인의 개수는:",cnt)
from collections import Counter
#ip별 트래픽 합계 구하기
ipTraffic = {}
with open(path) as f : #한글이 없으면 encoding 안해도 됨.
for line in f :
#print(line)
#읽어낸 한 줄을 공백을 기준으로 분할해서 list로 생성
a = line.split(" ")
try :
ipTraffic[a[0]] = ipTraffic.get((a[0]), 0) + int(a[9]) #'-'를 제거해줘야함.
except Exception as e:
print(e)
for ip in ipTraffic :
print(ip,":", ipTraffic[ip])
#상위 10개
counter = Counter(ipTraffic)
print(counter.most_common(10))
위와 같은 코드로 로그 분석을 수행 해볼 수 있다.
'LG 헬로비전 DX DATA SCHOOL > Python' 카테고리의 다른 글
Django REST API (0) | 2023.07.27 |
---|---|
Django (0) | 2023.07.26 |
파이썬 Data Type 및 처리 (0) | 2023.07.11 |
객체 지향 프로그래밍 (OOP) (0) | 2023.07.11 |
Python - 제어문과 함수 2 (0) | 2023.07.10 |