[오늘의 일지]
녹화 강의 - 멀티스레드, 멀티프로세싱, 일급객체, 클로저, 이터레이터, 제너레이터, 데코레이터
실시간 강의 - 파이썬 복습, 크롤링
[상세 내용]
파이썬 선택 추가 학습
멀티스레드
- 멀티스레드의 정의 : 멀티스레딩은 여러 코어에서 한 번에 여러 개의 스레드를 처리하는 CPU 성능을 활용하는 프로그래밍의 한 유형입니다.
- 멀티스레드 예시
import threading
# 스레드에서 실행할 함수
def work():
print("[sub] start")
keyword = input("[sub] 검색어를 입력하세요 >>>")
print(f"[sub] {keyword}로 검색을 시작합니다...")
print("[sub] end")
# 메인스레드 실행되는 부분
print("[main] start")
worker = threading.Thread(target=work)
worker.daemon = True # main이 종료될 때 sub가 같이 종료되는 기능
worker.start()
print("[main] 메인 스레드는 자기할일을 합니다..")
print("[main] end")
>>>
[main] start
[sub] start
[main] 메인 스레드는 자기할일을 합니다..
[main] end
[sub] 검색어를 입력하세요 >>>test
[sub] test로 검색을 시작합니다...
[sub] end
- 멀티스레드 예시(주식 매수, 매도)
import threading
import time
# 주식 자동매매
# 매수, 매도
# 매수 스레드
def buyer():
for i in range(5):
print("[매수] 데이터 요청 중...")
time.sleep(1) # 1초 기다리고 다음 코드 실행
print("[매수] 데이터 분석 중...")
time.sleep(1)
print("[매수] 매수 구간 진입중 입니다...")
time.sleep(1)
print("[매수] 매수를 시작합니다...")
time.sleep(1)
# 매도 스레드
def saler():
for i in range(5):
print("[매도] 데이터 요청 중...")
time.sleep(1)
print("[매도] 데이터 분석 중...")
time.sleep(1)
print("[매도] 매도 구간 진입중 입니다...")
time.sleep(1)
print("[매도] 매도를 시작합니다...")
time.sleep(1)
# 메인 스레드
print("[메인] start")
buyer = threading.Thread(target=buyer)
saler = threading.Thread(target=saler)
buyer.start()
saler.start()
buyer.join() # 매수 스레드가 종료될때까지 메인 스레드가 기다림
saler.join() # 매도 스레드가 종료될때까지 메인 스레드가 기다림
print("[메인] 장이 종료되었습니다.")
>>>
[메인] start
[매수] 데이터 요청 중...
[매도] 데이터 요청 중...
[매도] 데이터 분석 중...
[매수] 데이터 분석 중...
[매수] 매수 구간 진입중 입니다...
[매도] 매도 구간 진입중 입니다...
[매수] 매수를 시작합니다...[매도] 매도를 시작합니다...
[매수] 데이터 요청 중...[매도] 데이터 요청 중...
[매도] 데이터 분석 중...[매수] 데이터 분석 중...
[매도] 매도 구간 진입중 입니다...
[매수] 매수 구간 진입중 입니다...
[매도] 매도를 시작합니다...[매수] 매수를 시작합니다...
[매도] 데이터 요청 중...
[매수] 데이터 요청 중...
[매도] 데이터 분석 중...[매수] 데이터 분석 중...
[매수] 매수 구간 진입중 입니다...[매도] 매도 구간 진입중 입니다...
[매도] 매도를 시작합니다...
[매수] 매수를 시작합니다...
[매도] 데이터 요청 중...[매수] 데이터 요청 중...
[매도] 데이터 분석 중...[매수] 데이터 분석 중...
[매수] 매수 구간 진입중 입니다...[매도] 매도 구간 진입중 입니다...
[매수] 매수를 시작합니다...[매도] 매도를 시작합니다...
[매수] 데이터 요청 중...[매도] 데이터 요청 중...
[매수] 데이터 분석 중...
[매도] 데이터 분석 중...
[매도] 매도 구간 진입중 입니다...[매수] 매수 구간 진입중 입니다...
[매도] 매도를 시작합니다...
[매수] 매수를 시작합니다...
[메인] 장이 종료되었습니다.
멀티프로세싱
- 멀티프로세싱의 정의 : 멀티 프로세싱 (Multi Processing)이란, 여러 개의 CPU 코어가 동시에 작업을 처리하는 것을 의미합니다.
- 멀티프로세싱 예시
import multiprocessing as mp
# 프로세스에서 실행할 함수
def sub_process(name):
print("[sub] start")
print(name)
cp = mp.current_process()
print(f"[sub] pid : {cp.pid}")
print("[sub] end")
# if __name__ == "__main__" 사용하는 이유
# https://docs.python.org/2/library/multiprocessing.html#multiprocessing-programming
# 메인 프로세스
if __name__ == "__main__":
print("[main] start")
p = mp.Process(target=sub_process, args=('test_coding',))
p.start()
cp = mp.current_process()
print(f"[main] pid : {cp.pid}")
print("[main] end")
>>>
[main] start
[main] pid : 12024
[main] end
[sub] start
test_coding
[sub] pid : 12136
[sub] end
- 멀티프로세싱 예시
from multiprocessing import Process
import time
class Subprocess(Process):
def __init__(self, name):
Process.__init__(self)
self.name = name
def run(self):
print(f"[sub] {self.name} start")
time.sleep(5)
print(f"[sub] {self.name} end")
if __name__ == "__main__":
print("[main] start")
p = Subprocess(name='test_coding')
p.start()
p.join()
print("[main] end")
>>>
[main] start
[sub] test_coding start
[sub] test_coding end
[main] end
# 추가학습
# 1. 스레드간 데이터 처리 (lock)
# 2. 프로세스간 데이터 전송 (Queue, Pipe)
# 3. 속도 비교
# 4. 운영체제와 메모리
일급객체
- 일급객체 정의 : 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킵니다.
일급객체의 조건
- 다음과 같은 특징을 만족하는 객체를 말한다.
1. 데이터처럼 사용이 가능하다.
2. 매개변수에 넘겨줄 수 있다.
3. 리턴값으로 사용될 수 있다.
위에 조건에 의해 일반적으로 사용하는 함수가 여기에 포함되기도 합니다.
클로저
- 클로저 정의 : 함수가 종료되어도 자원을 사용할 수 있는 함수
# 내부 함수
# 함수 안에 또다른 함수를 정의할 수 있다.
def outer(name):
def inner():
print(name, "님 안녕하세요!")
return inner
func = outer("startcoding")
# func()
# 클로저
# 함수가 종료되어도 자원을 사용할 수 있는 함수
# ** 클로저가 될 조건
# 1) 내부 함수 여야 한다.
# 2) 외부 함수의 변수를 참조해야 한다.
# 3) 외부 함수가 내부 함수를 반환해야 한다.
def greeting(name, age, gender):
def inner():
print(name, "님 안녕하세요!")
print("나이: ", age)
print("성별: ", gender)
return inner
closure = greeting('이름', 나이, '성별')
closure()
# print(closure.__closure__[0].cell_contents)
for i in closure.__closure__:
print(i.cell_contents)
# 전역변수를 사용해서 대체가 가능하다.
# 전역변수 사용을 최소화 하는 것이 좋다 (네이밍문제, 스코프문제)
이터레이터
- 이터레이터 정의 : 이터레이터는 순서대로 다음 값을 리턴할 수 있는 객체를 의미합니다. 자체적으로 내장하고 있는 next 메서드를 통해 다음 값을 가져올 수 있는데 list, tuple과 같은 타입의 객체와는 다른 개념입니다.
- 이터레이터 생성 과정
# 이터레이터 생성방법
class Seasons:
def __init__(self):
self.season_list = ['spring', 'summer', 'autumn', 'winter']
self.idx = 0
self.max_num = 4
def __iter__(self):
return self
def __next__(self):
if self.idx < self.max_num:
curr_idx = self.idx
self.idx += 1
return self.season_list[curr_idx]
else:
raise StopIteration
# for i in Seasons():
# print(i)
iter_obj = Seasons().__iter__()
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__()) # 마지막에는 객체가 없기 때문에 에러가 납니다.
제너레이터
- 제너레이터의 정의 : 이터레이터에 의존하는 개념으로서 이터레이터를 사용해 자신의 실행을 제어하는 함수로서 범위로 따졌을 때는 제너레이터가 이터레이터에 속한다고 할 수 있습니다.
- 제너레이터 예시
# 제너레이터
# 1. 이터레이터를 만드는 함수
def season_generator(*args):
for arg in args:
yield arg
g = season_generator('spring', 'summer', 'autumn', 'winter')
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
# print(g.__next__())
def func():
print("첫번째 작업 중...")
yield 1
print("두번째 작업 중...")
yield 2
print("세번째 작업 중...")
yield 3
ge = func()
data = ge.__next__()
print(data)
data = ge.__next__()
print(data)
data = ge.__next__()
print(data)
데코레이터
- 데코레이터의 정의 : 함수의 앞, 뒤로 부가적인 기능을 넣어주고 싶을 때 사용한다
- 데코레이터 예시
# 데코레이터
# 함수의 앞, 뒤로 부가적인 기능을 넣어주고 싶을 때 사용
# 로깅, 권한확인
# 데코레이터 생성하기
def logger(func):
def wrapper(arg):
print("함수 시작")
func(arg) # 함수 실행
print("함수 끝")
return wrapper
@logger
def print_hello(name):
print("hello", name)
@logger
def print_bye(name):
print("bye", name)
print_hello('startcoding')
print_bye('fastcampus')
실시간 강의 내용 정리
파이썬 복습
- 삼항연산자 : 삼항연산자란 if else 문법을 마치 연산자와 같이 사용하는 것을 말합니다.
- 삼항연산자 사용 방법
# 일반 조건문
if 조건문:
조건이 참일 때 실행될 코드들
else:
조건이 거짓일 때 실행될 코드들
# 삼항연사자 사용시
(조건이 참일 때 실행될 코드) if 조건문 else (조건이 거짓일 때 실행될 코드)
- 리스트 컴프리헨션 : 반복문, 조건문 등의 제어문과 함께 리스트를 한 줄의 코드로 만들 수 있게 해주는 파이썬 문법입니다.
- 리스트 컴프리헨션 예시
# 기본적인 for문을 이용한 리스트 만들기
numbers = []
for i in range(1, 11):
numbers.append(i)
# 리스트 컴프리헨션을 사용하면
numbers = [i for i in range(1, 11)]
# 리스트 컴프리헨션 기본적인 형태
(리스트에 넣고자 하는 변수) for 변수 in 리스트 (혹은 range 등)
# 일반적인 for문에서 if문을 쓰는 상황
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
filterd_numbers = []
for i in numbers:
if i >= 4:
filterd_numbers.append(i)
# 리스트 컴프리헨션을 사용하면
filtered_numbers = [number for number in numbers if number >= 4]
# 조건문에서 리스트 컴프리헨션 기본적인 형태
(리스트에 넣고자 하는 변수) for 변수 in 리스트 (혹은 range 등) if (조건문)
- lambda 표현식과 map, filter, reduce
- lambda 함수
# 기본적인 형태
lambda 매개변수 : 식 (리턴값)
# 일반 함수
def plus(x, y):
return x + y
# lambda 를 사용하면
lambda x, y: x + y
# 사용할 때는 이런 방식으로 마지막에 넣어줍니다.
result = (lambda x, y: x + y)(1, 2) # x에 1, y에 2가 들어가고, x+y인 3이 리턴됨
print(result)
>>>3
- map 함수 : map함수는 함수와 리스트(반복 가능 객체)를 인자로 받고, 리스트 요소 각각에 해당 함수를 적용시킨 새로운 리스트를 반환해 주는 함수입니다.
# 기본적인 형태
map(함수, 반복가능객체(리스트 등))
# [1,2,3]라는 리스트가 있을 때 각 요소에 10을 더하고 싶은 상황
my_list = [1, 2, 3]
new_list = map(lambda x: x+10, my_list)
# [1, 2, 3] 이라는 리스트 내부 요소 각각마다 x+10 이 수행됨
# new_list = [i+10 for i in my_list] 와 동일
print(list(new_list))
>>>
[11, 12, 13]
# map 은 항상 map 객체를 리턴하기 때문에, 리스트로 사용하려면 list() 로 한번 감싸주어야함
- filter 함수 : filter함수는 함수와 리스트(반복 가능 객체)를 인자로 받고, 리스트 요소 중에 해당 함수의 return값이 True인 것만을 반환해 주는 함수입니다.
# 기본적인 형태
filter(조건으로 쓰고자 하는 함수, 반복가능객체(리스트 등))
# [1,2,3,4,5]라는 리스트가 있을 때 2만 남기고 싶은 상황
my_list = [1, 2, 3]
new_list = filter(lambda x: x == 2, my_list) # x == 2 이라는 조건을 충족하는 요소만 남음
print(list(new_list))
>>>
[2]
- reduce 함수 : reduce 함수는 함수와 리스트(반복 가능 객체)를 인자로 받고 각 인자마다 함수를 거쳐서 리턴된 값을 쌓아나가는 함수입니다.
# 기본적인 형태
reduce(함수, 반복가능객체(리스트 등))
# 예제
from functools import reduce
my_list = [1, 2, 3, 4, 5]
result = reduce(lambda x, y: x + y, my_list)
print(result)
>>>
15
# 과정설명
# 1. reduce 함수가 실행되면, 우선 x에는 첫번째 리스트 요소인 1이, y에는 두번째 리스트 요소인 2가 들어갑니다. 그러면 3이 리턴됩니다.
# 2. 그 다음으로, y에는 세번째 리스트 요소인 3이, x에는 앞서 리턴된 값인 3이 들어갑니다. 그러면 6이 리턴됩니다.
# 3. 그 다음으로, y에는 네번째 리스트 요소인 4가, x에는 앞서 리턴된 값인 6이 들어갑니다. 그러면 10이 리턴됩니다.
# 4. 그 다음으로, y에는 다섯번째 리스트 요소인 5가, x에는 앞서 리턴된 값인 10이 들어갑니다. 그러면 15가 리턴됩니다.
# 5. 결과적으로 15가 리턴됩니다.
크롤링
- 크롤링의 정의 : 크롤링이란 웹 페이지로부터 데이터를 추출하는 행위를 말합니다.
- 크롤링을 하는 방법 : 우선 크롬 환경에 들어가서 개발자 도구를 활용해서 HTML 문서라는 것을 확인해 봅니다.
- 맥 → Command + Option + I
- 윈도우 → F12
- 개발자 도구를 켜고 아래의 이미지에 왼쪽에 있는 버튼을 누르면 특정 부분의 HTML 문서의 위치를 자세하게 확인할 수 있습니다.
- 특정 부분에 마우스를 가져가면 그 부분의 HTML문서를 확인할 수 있습니다.
- 파이썬에서 Request를 사용해서 웹페이지에 요청하는 방식이 있습니다.
- Request 사용 방법
# 패키지 설치 및 모듈 사용
pip install requests
import requests
# get 요청
requests.get(주소)
# 에시
response = requests.get('https://www.naver.com')
print(response.text) # .text 를 붙이면 데이터 부분 출력
# post 요청 보내기
requests.post(주소, 요청 데이터)
- HTML과 웹 스크래핑
- 선택자 : HTML 문서의 특정 부분에 이름을 붙인 것을 말하며 그 이름을 가지고 필요한 데이터를 찾을 수 있다.
# 아래 HTML 문서에 id와 class라는 선택자를 추가하면 훨씬 보기도 쉽고, 관리하기 쉬워집니다
<html>
<head>
</head>
<body>
<h1> 장바구니
<p id='clothes' class='name' title='라운드티'> 라운드티
<span class = 'number'> 25 </span>
<span class = 'price'> 29000 </span>
<span class = 'menu'> 의류</span>
<a href = 'http://www.naver.com'> 바로가기 </a>
</p>
<p id='watch' class='name' title='시계'> 시계
<span class = 'number'> 28 </span>
<span class = 'price'> 32000 </span>
<span class = 'menu'> 액세서리 </span>
<a href = 'http://www.facebook.com'> 바로가기 </a>
</p>
</h1>
</body>
</html>
- BeautifulSoup 사용
# 패키지 설치 및 모듈 사용
pip install beautifulSoup4
# bs4라는 패키지로부터 BeautifulSoup라는 모듈을 임포트
from bs4 import BeautifulSoup
# HTML 문서를 문자열 html로 저장
html = '''
<html>
<head>
</head>
<body>
<h1> 장바구니
<p id='clothes' class='name' title='라운드티'> 라운드티
<span class = 'number'> 25 </span>
<span class = 'price'> 29000 </span>
<span class = 'menu'> 의류</span>
<a href = 'http://www.naver.com'> 바로가기 </a>
</p>
<p id='watch' class='name' title='시계'> 시계
<span class = 'number'> 28 </span>
<span class = 'price'> 32000 </span>
<span class = 'menu'> 액세서리 </span>
<a href = 'http://www.facebook.com'> 바로가기 </a>
</p>
</h1>
</body>
</html>
'''
# BeautifulSoup 인스턴스 생성. 두번째 매개변수는 분석할 분석기(parser)의 종류.
soup = BeautifulSoup(html, 'html.parser')
# soup.select('태그명') : 태그를 입력으로 사용할 경우
# soup.select('.클래스명') : 클래스를 입력으로 사용할 경우 (`.` 은 클래스를 뜻하는 특수기호입니다.)
# soup.select('#아이디') : ID를 입력으로 사용할 경우 (`#` 은 id를 뜻하는 특수기호입니다.)
# soup.select('상위태그명 하위태그명') : 자손 관계 (어떤 태그 내부에 있는 모든 태그를 자손이라고 함)
# soup.select('상위태그명 > 하위태그명') : 자식 관계 (어떤 태그 내부에 있는 태그 중 바로 한 단계 아래에 있는 태그를 자식이라고 함)
# soup.태그명
#soup.태그명을 사용하시면 해당 태그를 포함하여 그 태그가 끝나는 부분까지의 문장을 가지고 옵니다.
# 단, 해당 태그가 여러개 있다면 첫번째 태그만 가져옵니다.
<a href="http://www.naver.com"> 바로가기 </a>
soup.a
# soup.태그명.get('속성명')
# get('속성명')을 사용하시면 해당 속성의 값을 가져옵니다.
# 만약 a 태그가 href = 'http://www.naver.com' 라는 속성을 가지는 경우,
# get('href')를 하면 'http://www.naver.com'의 값을 가져오게 됩니다.
<a href="http://www.naver.com"> 바로가기 </a>
soup.a.get('href')
>>>
http://www.naver.com
[마무리]
오늘은 녹화 강의부터 실시간 강의까지 새로운 내용을 많이 배웠습니다. 그래서 아직까지는 머릿속에 다 들어오지 못한 느낌을 많이 받은 거 같습니다. 특히 크롤링 파트는 앞으로도 개발자가 되기 위해서 중요하게 사용될 부분인 만큼 실습 위주로 복습을 진행해야겠다고 느꼈습니다.
'프로그래밍 > Python' 카테고리의 다른 글
[AI 부트캠프] DAY 40 - 코딩 테스트 1 (0) | 2023.09.12 |
---|---|
[AI 부트캠프] DAY 15 - 파이썬 9 (0) | 2023.08.05 |
[AI 부트캠프] DAY 13 - 파이썬 7 (0) | 2023.08.03 |
[AI 부트캠프] DAY 12 - 파이썬 6 (0) | 2023.08.02 |
[AI 부트캠프] DAY 11 - 파이썬 5 (0) | 2023.08.01 |
댓글