최신판 |
당신의 편집 |
1번째 줄: |
1번째 줄: |
| 여기서는 [[Python]]에서 사용하는 고급 테크닉과 각종 응용 라이브러리를 사용하는 방법에 대해 소개하고자 합니다. | | 여기서는 [[Python]]에서 사용하는 고급 테크닉과 각종 응용 라이브러리를 사용하는 방법에 대해 소개하고자 합니다. |
|
| |
| == 비동기 프로그래밍 ==
| |
| asyicio라는 모듈을 이용해서 비동기 작업을 할 수 있습니다. 동기식 프로그래밍이 작업이 완전히 끝난 후에 다른 작업을 시작하는 방식이 아닌 어떤 작업이 진행되는 도중에 다른 작업을 진행하는 방식으로 진행하는 겁니다. 대량으로 데이터를 다운로드받아서 크롤링을 할 때에 유용하게 사용할 수 있습니다. 다운로드 받는 작업은 리소스를 많이 잡아먹지 않는 것에 비해 상당히 오래 걸릴 수 있기에 파일 하나를 다운로드 받은 뒤에 다음 파일을 다운로드하는 식으로 진행하면 시간이 오래 걸리는데, 비동기 프로그래밍을 이용하면 이런 시간을 상당히 단축시킬 수 있습니다.
| |
|
| |
| 원인 미상의 오류로 Spyder, Jupyter Notebook 같은 iPython 기반 콘솔에서는 asyncio 모듈이 구동이 잘 됩니다.
| |
|
| |
| 비동기 프로그래밍을 하기 위해서는 비동기 함수를 나타내는 키워드인 <code>async</code>와 입력 대기를 나타내는 키워드인 <code>await</code>를 사용합니다. 이제 사용법을 확인해봅시다.
| |
| <syntaxhighlight lang='python'>
| |
| import asyncio, time, requests
| |
|
| |
| KEYWORDS = ['리브레 위키', '미디어위키', '대한민국', '파이썬', '중식', 'SCP재단']
| |
|
| |
|
| |
| # 구글 검색 결과를 HTML로 크롤링하기
| |
| def txt_show(word):
| |
| res = requests.get(f"https://google.co.kr/search?q={word}")
| |
| txt = res.text
| |
| return txt
| |
|
| |
| # 동기식 프로그래밍 시간 재기
| |
| cur_time = time.time()
| |
| # 동기식 반복문
| |
| for word in KEYWORDS:
| |
| print(len(txt_show(word)))
| |
| time_lapsed = time.time() - cur_time
| |
| print(time_lapsed)
| |
|
| |
| # 비동기식 함수 정의
| |
| async def get_txts(word):
| |
| loop = asyncio.get_event_loop() # 이벤트 루프 정의
| |
| txt = await loop.run_in_executor(None, txt_show, word) # 이벤트 루프를 이용해서 함수 txt_show 실행. 입력값 word
| |
| return len(txt)
| |
|
| |
| async def main(): #반복 실행할 함수
| |
| futures = [get_txts(word) for word in KEYWORDS] # 비동기 함수 결과값을 모으자
| |
| # 비동기 함수 get_txts의 결과깂을 퓨처 형태의 이터레이터로 표시
| |
| res = await asyncio.gather(*futures) # gather 함수를 이용해서 결과값 출력
| |
| print(res) # res 값 출력
| |
|
| |
| # 비동기식 프로그래밍 시간 재기
| |
| cur_time = time.time()
| |
| asyncio.run(main()) # 실행할 때에는 asyncio.run 함수를 사용한다.
| |
| time_lapsed = time.time() - cur_time
| |
| print(time_lapsed)
| |
| </syntaxhighlight>
| |
|
| |
| 우선 개별 작업할 함수들은 <code>loop=asyncio.get_event_loop()</code>를 호출해서 이벤트 루프를 생성합니다. 그 다음에 <code>loop.run_in_executor</code> 함수를 이용해서 이벤트 루프의 값을 모읍니다. 위의 get_txts 함수의 경우 출력값 txt는 함수의 결과값을 생성하는 이벤트가 됩니다. 가장 중요한 것이 바로 main 함수인데요. get_txts의 결과깂을 모은 리스트 futures를 잡고, <code>asyncio.gather</code> 함수를 이용해서 futures에 정의된 이벤트들(여기서는 KEYWORDS에 있는 단어들에 대해 구글 검색 결과의 html 텍스트 추출) 실행시켜 줍니다.
| |
|
| |
| 위의 코드는 time 함수를 이용해서 순차적으로 html을 수집했을 때 걸리는 시간과 비동기 프로그래밍을 이용해서 html을 수집했을 때 걸리는 시간을 측정하는 코드입니다. 놀랍게도 시간 단축 효과가 확실한 것을 알 수 있죠.
| |
|
| |
|
| |
| == 유용한 표준 라이브러리 ==
| |
| 파이썬은 몇몇 유용한 표준 라이브러리를 제공합니다. 표준 라이브러리를 사용할 때에는 다음과 같은 형식으로 호출하면 됩니다.
| |
| <syntaxhighlight lang='python'>
| |
| import functools # 라이브러리 자체를 호출하고 싶을 때
| |
| from functools import reduce # 라이브러리의 함수/클래스를 호출하고 싶을 때. 이것만 사용하면 functools 라이브러리 자체는 사용할 수 없습니다.
| |
| from itertools import combinations as cp # 라이브러리의 호출된 함수/클래스의 이름을 바꾸고 싶을 때
| |
| </syntaxhighlight>
| |
| === functools ===
| |
| functools는 몇몇 함수들과 데코레이터들을 사용할 수 있습니다. 가장 유용하게 사용할 수 있는 함수는 바로 reduce 함수인데요. 이것은 리스트와 함수가 있을 때 연쇄적으로 함수를 실행시켜줍니다. 사용할 때에는 <code>reduce(합병할 함수, 리스트, 초기값)</code> 형식으로 사용하면 됩니다. 예를 들면 주어진 리스트에 대해 숫자의 곱을 표현할 때에는 다음과 같은 함수를 사용하면 됩니다.
| |
| <syntaxhighlight lang='python'>
| |
| from functools import reduce
| |
|
| |
| exp_list = [4,5,1,2,2.5]
| |
| res = reduce(lambda x,y: x*y, exp_list, 1) # 곱함수, 숫자 곱할 리스트, 초기값
| |
| print(res)
| |
| </syntaxhighlight>
| |
|
| |
|
| == 웹 개발 라이브러리 == | | == 웹 개발 라이브러리 == |