[2024.10.07] 필수 온라인 강의 Part1 파이썬 라이브러리 활용 프로젝트 CH01 파이썬 라이브러리의 이해
인코딩과 디코딩
인코딩(Encoding) = 코드화 = 암호화 = 부호화
- 인코딩 : 컴퓨터에서 인코딩은 동영상이나 문자 인코딩 뿐 아니라 사람이 인지할 수 있는 형태의 데이터를 약속된 규칙에 의해 컴퓨터가 사용하는 0과 1로 변환하는 과정
- 'ASCII', 'URL인코딩', 'HTML인코딩', 'Base64인코딩', '유니코드(https://home.unicode.org/) 인코딩' 등이 존재
a = "Life is too short"
type(a) -> str 형식
b = a.encode('utf-8') # utf-8 인코딩 (가장 많이 사용되는 유니코드 인코딩)
type(b) -> bytes 형식
b = b'Life is too short'
# 한글 인코딩 예시
a = '한글'
a.encode('utf-8') -> b'\xed\x95\x9c\xea\xb8\x80' 출력
디코딩(Decoding) = 역코드화 = 복호화
- 사람이 이해할 수 있는 언어로 돌려주는 것
- 유니코드 변환 사이트 : https://checkserp.com/encode/unicode/
b.decode('utf-8') -> '한글'
b.decode('ascii') # 다른 디코더로 디코딩할 시 : 에러 발생 : 디코드 에러 - 꼭 인코딩했던 걸로 디코딩하기
- 꼭 인코딩 했던 언어로 디코딩을 해야한다 : 아니면 UnicodeDecodeError 발생
- 소스 코드의 인코딩 디코딩
- 소스 코드 파일이 현재 어떤 방식으로 인코딩되었지 명시하는 방법
- 파이썬 셸이 아닌 편집기로 코딩할 때는 소스 코드의 인코딩이 매우 중요
#-*- coding: ascii -*-
a = '한글이 보입니다!'
- Python 2.X 버전은 ascii 가 기본 인코딩 방식
# -*- coding: utf-8 -*-
a = '한글이 보입니다!'
- Python 3.0 부터는 utf-8 이 기본 인코딩 방식
클로저와 데코레이터
클로저(Closure) : 함수 안의 함수를 결과로 반환할 때, 그 내부 함수를 클로저(Closure) 라고 합니다.
- 사용되는 곳 : 콜백(Callback) 함수에 사용, 함수의 순차적 실행, 데코레이터 함수
- 클래스(Class) 사용하기
class Mul: # 클래스 생성
def __init__(self, m): # 클래스를 생성하는 함수 __init__
self.m = m # init을 받아서 내부함수 m에 저장을 한다는 의미
def mul(self, n):
return self.m * n
if __name__ == "__main__": # 파이썬프로그램을 만들고 모듈을 실행시킬때 쓰는 구문 main은 아래를 실행해라는 의미
mul3 = Mul(3)
mul5 = Mul(5)
print(mul3(10)) # 30 출력
print(mul5(10)) # 50 출력
class Mul:
def __init__(self, m):
self.m = m
def __call__(self, n): # mul 함수를 __call__ 함수명으로 변경, Mul함수보다 더 간결
return self.m * n
if __name__ == "__main__":
mul3 = Mul(3)
mul5 = Mul(5)
print(mul3(10)) # 30 출력
print(mul5(10)) # 50 출력
- 클로저(Closure) 사용하기
def mul(m): # 외부 함수
def wrapper(n): # 내부 함수 (클로저)
return m * n
return wrapper # 함수가 두개이므로, return도 2개가 들어거야한다
if __name__ == "__main__":
mul3 = mul(3) # m = 3 인 wrapper 함수가 mul3 에 저장
mul5 = mul(5) # m = 5 인 wrapper 함수가 mul5 에 저장
print(mul3(10)) # m = 3, n = 10 인 wrapper 함수가 실행
print(mul5(10)) # m = 5, n = 10 인 wrapper 함수가 실행
데코레이터 (Decorator)
- 꾸미다, 장식하다'라는 뜻으로 함수를 꾸며주는 함수. : 보조적인 함수
- 함수를 인수로 받는 클로저 : 클로저의 종류 중 하나라고 이해하기
- @를 이용한 어노테이션으로 사용
- 사용되는 곳 : 반복되는 작업을 여러 함수에 적용할 경우, 기존 함수를 수정하지 않고 추가 기능을 구현하고 싶을 경우
import time
def func1(a, b): #func1 함수에 a와 b라는 인자를 받아서,
start = time.time()
print("함수가 실행됩니다.")
val = a + b #두개의 인자를 더해서 출력하는 함수
end = time.time() # 함수 실행 시간을 측정
print("함수 수행시간: %f 초" % (end-start))
return val
if __name__ == "__main__":
result = func1(1, 2)
print(result)
def func2(a, b): #func2함수는 a와 b라는 인자를 받아서
start = time.time()
print("함수가 실행됩니다.")
val = a * b
end = time.time()
print("함수 수행시간: %f 초" % (end-start))
return val
if __name__ == "__main__":
result = func2(1, 2)
print(result)
-> 위의 1번 2번 함수가 중복이 되어있다. 이를 해결하기 위해서 데코레이터를 쓰면 된다
- 데코레이터 만들기
def func1(a, b): # 각 함수의 메인 기능 만들기
val = a + b
return val
def func2(a, b):
val = a * b
return val
# ''' 실행 시간 측정 데코레이터 '''
def elapsed(func): # 함수를 인풋으로 받는다.
def wrapper(a, b):
print('함수가 실행됩니다.')
start = time.time()
result = func(a, b) # 함수 실행
end = time.time()
print("함수 수행시간: %f 초" % (end - start)) # 함수 수행시간
return result # 함수 실행 결과 반환
return wrapper
if __name__ == "__main__":
deco1 = elapsed(func1) # 1번 함수를 이용하겠다는 의미
result = deco1(1,2) # 데코레이터 정의하고 인자에 숫자를 넣어줌
print(result)
if __name__ == "__main__":
deco2 = elapsed(func2) # 2번 함수를 이용하겠다는 의미
result = deco2(1,2) # 데코레이터 정의하고 인자에 숫자를 넣어줌
print(result)
@elapsed #@를 붙여서 데코레이터를 만들기 -> 따로 데코레이터 정의 없이 바로 함수 사용 가능
def func1(a, b):
val = a + b
return val
@elapsed
def func2(a, b):
val = a * b
return val
if __name__ == "__main__":
result = func1(1,2) # 바로 1번 함수 사용가능
print(result)
if __name__ == "__main__":
result = func2(1,2) # 바로 2번 함수 사용가능
print(result)
이터레이터와 제네레이터
이터레이터(Iterator) : 집합에서 값을 차례대로 꺼낼 수 있는 객체(Object)
- for 문을 순회할 수 있는 객체
- 사용 이유 : 숫자가 아주 많을 경우 미리 만들어 놓는 것 보다
그때 그때 필요할 때 값을 뽑아 사용하고 싶을 경우가 대부분의 상황에서 효율적 (메모리 등)
- 반복 가능 (Iterable) 객체에만 사용 가능
- iter() 로 반복 가능 객체 변환
- next() 로 다음값 뽑기
- 한번 반복하면 다시 사용될 수 없음
for a in [1, 2, 3]:
print(a) -> 1, 2, 3 각각이 출력
이터레이터 만들기
a = [1,2,3]
iterator = iter(a)
next(iterator) # 첫번째 호출 -> 1출력
next(iterator) # 두번째 호출 -> 2출력
next(iterator) # 세번째 호출 -> 3출력
next(iterator) # 네번째 호출 -> StopIteration이라는 에러 발생 : 한번만 쭉 가는 구조
for a in iterator:
print(a) -> 아무것도 출력이 안 됨 : 위에서 다 뽑아서 써서 for문에서 쓸 게 없다는 의미 : 쓰고 싶으면 이터레이터를 재정의해야함
제너레이터(Generator) : yield()
- 이터레이터 (Iterator) 를 생성해주는 함수
- 사용이유 : 함수가 하나의 고정된 값을 반환하는 것이 아닌 순차적으로 다른 값을 반환하기 원할 때
def generator(): #generator라는 함수를 만들고
yield 'a' #a, b, c를 순차적으로 넣는 함수
yield 'b'
yield 'c'
next(g) # 첫번째 호출 -> 'a' 출력
next(g) # 두번째 호출 -> 'b' 출력
next(g) # 세번째 호출 -> 'c' 출력
next(g) # 네번째 호출 -> StopIteration 출력 : 이터레이터는 한번만 출력
def client_count(total_client): # 제너레이터 사용 예시
n = 1 # n번째 고객을 의미
for num in range(total_client):
print(f'{n} 번째 고객님 입장하십시오!')
n += 1
yield
mygen = client_count(100)
next(mygen) -> 1 번째 고객님 입장하십시오! 출력
next(mygen) -> 2 번째 고객님 입장하십시오! 출력
next(mygen) -> 3 번째 고객님 입장하십시오! 출력
변수 타입 어노테이션
타입 어노테이션 (Type Annotation)
- 변수나 상수를 선언할 때 그 타입을 명시적으로 선언해 줌으로써 어떤 타입의 값이 저장될 것인지를 직접 알려주는 방법
- 프로그램은 수많은 함수, 클래스 등으로 복잡하게 얽혀있는 경우가 많음 -> 변수 타입이 맞지 않으면 에러나 버그의 발생 가능성이 높아짐 : 이를 방지하기 위한 사용
- 사용 시, 코드 가독성과 협업 효율성이 높아짐
- Python 3.5 부터 기능이 지원되어 많은 라이브러리, 프로젝트에서 사용이 확산되는 추세
- 정적 프로그래밍 언어(statically typed language) : 컴파일 시 변수 타입이 결정됨 ( Java, C, C++ 등)
- 동적 프로그래밍 언어(dynamic programming language) : 프로그램 실행 도중 변수 타입을 동적으로 바꿀 수 있음(파이썬 등)
- 장점
- 타입에 자유로워 유연한 코딩이 가능하므로 쉽고 빠르게 프로그램을 만들 수 있음
- 타입 체크를 위한 코드가 없으므로 비교적 깔끔한 소스 코드
- 단점
- 프로젝트의 규모가 커질수록 잘못된 타입 사용으로 말미암은 버그가 생길 확률 높아짐
- 타입 어노테이션이 없을 시, 정적 프로그래밍 언어와 타입 버그 발생 시 원인 찾기 어려움
- 실행속도가 느림
# Python
a = int(1) #int임
a = str("1") # int에서 자동으로 str로 바뀜
type(a)
타입 어노테이션을 안해줘도 상관이 없다! 하지만 해주는 게 좋음!! -> 나중에 에러가 날 수 있음
# 파이썬 타입 어노테이션
a: int = 10
a # -> 10 이 출력
def add(a: int, b: int) -> int:
return a + b
add(1, 2) # 3이 출력
add("1", "2") # 에러가 발생하지는 않음 , 대신 12가 출력 : 문자열 덧셈의 출력
add.__annotations__ # 타입 어노테이션 확인 {'a': int, 'b': int, 'return': int} 출력
문자열 처리 - str()과 repr()
- str() 과 repr() 함수 : 객체를 문자열로 반환하는 함수
- str() 은 비공식적인 문자열을 출력, 사용자가 보기 쉽도록/ 프로그램 사용자를 위해
- repr() 은 공식적인 문자열을 출력 (시스템에서 인식가능), 문자열로 객체를 다시 생성/ 프로그램개발자를 위해
a = 123
str(a) # '123'출력
repr(a) # '123'출력
- 숫자의 경우 동일함
a = "Hello World !"
str(a) # 'Hello World !' 출력
repr(a) # "'Hello World !'" 출력 : 큰따옴포 안에 작은 따옴표가 있음
- 출력에 차이가 있음 : repr는 객채형태 그대로 출력이 된다.
import datetime
a = datetime.datetime(2022, 1, 1)
str(a) # '2022-01-01 00:00:00' 출력
repr(a) # 'datetime.datetime(2022, 1, 1, 0, 0)' 출력
- repr는 객채형태 그대로 출력이 된다.
- 문자열을 객체로 변환할 때 : eval()
a = "Hello World !"
b = str(a)
eval(b) # 에러발생함
a = "Hello World !"
b = repr(a)
eval(b) # 에러발생하지 않음 : 'Hello World !' 출력
- 사용자가 보기 쉬운 형태는 시스템이 이해하는 형식은 아니다 : 변환을 할 수가 없다.
외부 라이브러리 다루기 - pip
- 방법 1. Pycharm 패키지 매니저 사용
- 방법 2. pip 사용
- 설치 : pip install 패키지명
- 삭제 : pip uninstall 패키지명
- 특정 버전으로 설치 : pip install 패키지명==버전
- 패키지 버전 업그레이드 : pip install --upgrade 패키지명
- 설치된 패키지 확인 : pip list
- 패키지 리스트 파일로 저장 : pip list --format=freeze > requirements.txt
- 패키지 리스트 설치 : pip install -r requirements.txt)
'Study > Python' 카테고리의 다른 글
파이썬 라이브러리 활용 프로젝트 - 파이썬 환경 세팅하기 (7) | 2024.10.07 |
---|---|
파이썬 라이브러리 - BeautifulSoup (웹 데이터 수집 라이브러리) (1) | 2024.09.30 |
파이썬 라이브러리 - Seaborn(데이터 시각화) (0) | 2024.09.30 |
파이썬 라이브러리 - Matplotlib (데이터 시각화) (0) | 2024.09.30 |
파이썬 라이브러리 - Pandas (데이터 자료 처리 라이브러리) (1) | 2024.09.27 |