해당 내용은 Datacamp의 Data engineering track을 정리했습니다.
Writing Functions in Python의 chapter 2에 대한 내용입니다.
기본적인 내용보다는 강의를 들으면서 처음 알게 된 내용을 위주로 작성했습니다.
해당 포스팅에는 아래의 내용을 포함하고 있습니다.
- context manager 사용과 만들기
- Nested context manager
- 에러 핸들링
1. Using context managers
context manager는 context를 불러오고 원하는 코드를 실행한 뒤 해당 context를 제거하는 역할을 수행합니다. 보통 흔히 많이 사용하고 있는 context manager는 with문과 함께 사용됩니다.
with open('my_file.txt') as my_file:
text = my_file.read()
length = len(text)
print('The file is {} characters long'.format(length))
일반적으로 file.open을 하면 file.close로 닫아줘야 합니다. 하지만, with문과 같이 context manager를 사용하면, 자동으로 file.close를 해주기 때문에 굳이 close를 해주지 않아도 됩니다.
with <context-manager>(<args>) as <variable-name>:
# Run your code here
# This code is running "inside the context"
# This code runs after the context is removed
기본적으로 위의 예시처럼 사용되고 as는 context-manager에 의해 반환되는 값을 할당할 변수로 이해하시면 좋습니다. 위의 open('my_file.txt')를 my_file에 할당한 것과 동일합니다.
2. Writing context managers
context manager를 정의할 수 있는 방법은 class나 function 형태로 가능합니다. 이번 강의에서는 Function으로 구현하는 방법을 소개합니다.
@contextlib.contextmanager
def my_context():
# Add any set up code you need
yield
# Add any teardown code you need
위와 같은 형태로 context manager를 구현할 수 있습니다. yield 위에는 context를 불러오는 코드를 작성하고, yield 아래에는 context를 제거하는 코드를 작성하면 됩니다.
@contextlib.contextmanager
def database(url):
# set up database connection
db = postgres.connect(url)
yield db
# tear down database connection
db.disconnect()
url = 'http://datacamp.com/data'
with database(url) as my_db:
course_list = my_db.execute('SELECT * FROM courses')
위의 코드는 db로 연결하는 context manager를 활용한 예입니다.
3. Advanced topics
이번 강의에서는 중첩된 컨텍스트, 오류 처리 등에 대해 다룹니다. 하나의 파일 내용을 다른 파일로 옮기려고 한다면, 다음과 같이 컨텍스트를 병렬적으로 활용할 수 있습니다.
def copy(src, dst):
with open(src) as f_src:
contents = f_src.read()
with open(dst, 'W') as f_dst:
f_dst.write(contents)
위의 코드처럼 병렬적으로 파일을 처리했을 때, 파일 용량이 굉장히 크다면 모든 내용을 불러오기 전에 에러가 날 수 밖에 없을 것입니다. 이러한 문제를 해결하기 위해서 1줄씩 불러서 입력하는 방식을 활용할 수 있습니다.
def copy(src, dst):
with open(src) as f_src:
with open(dst, 'w') as f_dst:
for line in f_src:
f_dst.write(line)
만약 에러가 발생했을 때에 발생하는 오류를 핸들링하기 위해서는 try, except, finally를 사용하면 됩니다.
try:
# code that mighet raise an error
except:
# do something about the error
finally:
# this code runs no matter what