Python Tricks - 파이썬 코드를 정돈하기 위한 패턴
이 글은 댄 베이더의 Python Tricks를 읽고 쓰는 글입니다.
가장 첫 주제로 등장한 파이썬 코드를 정돈하기 위한 패턴에서는 개인적으로 좋은 코드를 위한 습관에 가까운 내용이 많았다고 생각합니다.
1. assert문으로 방어하기
assert가 어떠한 함수 및 변수가 특정 값임을 체크하는 용도로 디버깅 단계에서 사용되는 것임을 알았지만, 실제로 사용하는 일이 거의 없었습니다.
if문으로 처리하여 exception 처리하는 것 또한 하나의 assert 방식이라고 생각 할 수 있지만 개발 단계에서 assert를 사용하는 것이 직관적이라고 합니다.
또한 중요한 점은 인터프리터의 설정을 통해 모든 assert를 비활성화 할 수 있기 때문에 if문으로 예외 발생으로 심어놓은 코드를 삭제하지 않아 생기는 휴먼 에러등을 방지 할 수 있습니다. 개인적으로 이 점이 중요 한 것 같습니다.
대신 if문이 들어가야 하는 부분에 assert가 들어가면 안됩니다. 이 경우 서비스적으로 충족해야하는 조건이 비활성화로 인해 동작하지 않을 수 있습니다.
2. 보기 좋은 쉼표 표시
이 점은 확실히 개발 습관으로 가져가야 할 것 같습니다.
가끔 딕셔너리를 사용 할 때 , 표시를 마지막 값 이후에 적어놓기는 하지만 대체로는 맞춰서 쓰고 있었습니다. 인터프리터에서 특정 라인에 문제가 발생하면 해당 라인을 출력해줍니다.
그래서 리스트나 딕셔너리를 사용 할 때 값을 내려쓰고 있습니다.
예를 들면
list_ = [
'hi',
'hello',
'nihaoma',
'gonichiwa'
]
이러한 방식으로 저장하고 있습니다. 그런데 문제는 다음 값을 추가 할 때 입니다. 만약 그 다음으로 ‘e’를 추가하는데 ,를 적지 않으면 어떻게 될까요?
list_ = [
'hi',
'hello',
'nihaoma',
'gonichiwa'
'안녕'
]
# ['hi', 'hello', 'nihaoma', 'gonichiwa안녕']
답은 아래와 같이 gonichiwa와 안녕이 붙어서 출력됩니다. 생각해 본 적이 없는 문제였는데 이 책을 통해 명확하게 알게되어 정말 다행이라는 생각이 들었습니다.
그렇기에 책에서는 마지막의 값 이후에 , 를 추가해주면 좋다고합니다.
list_ = [
'hi',
'hello',
'nihaoma',
'gonichiwa',
]
이렇게 리스트를 만들어도 정상적으로 만들어짐을 확인 할 수 있었습니다.
3. Context Manager와 with
실무에서 with을 사용 할 때는 꽤 다양합니다. 제가 with을 사용하던 사례는 다음 정도가 되겠네요.
- DB 세션을 만들 때
- 파일 입출력을 위해 파일 객체를 열 때
- async를 이용한 HTTP 요청을 하기 위해 aiohttp 객체 만들때
특히 데이터베이스와 파일 입출력은 with의 거의 대표적인 사례가 될 것 같습니다. 가장 일반적인 파일 입출력으로 간단한 예제를 만들면 다음과 같습니다.
with open('./write_test.csv','w') as f:
f.write('일단,써보는,파일입출력')
with open('./write_test.csv','r') as f:
a = f.read()
print(a)
#일단,써보는,파일입출력
여기서 with은 파일의 객체를 리턴해주고 Exception이 발생하거나 혹은 작업이 모두 끝난 뒤에 마지막으로 파일을 닫아주는 역할을 합니다.
여기서 사용되는 with은 파이썬의 내장 함수를 이용하여 자체적으로 만들 수 있습니다. 여기서 사용되는 함수는 __enter__과 __exit__입니다.
with으로 해당 객체를 생성하면 __enter__이 1회 실행됩니다. 그리고 범위안의 모든 작업이 끝나면 마지막으로 __exit__를 실행하고 끝납니다.
데이터베이스는 세션을 열고 객체를 리턴하는 것이 __enter__부분이 되고 모든 작업을 끝내거나 예외로 인해 불가피하게 닫힐 경우 __exit__를 통해 세션을 닫아주는 방식입니다.
try, finally 보다도 자주 사용되는 자원을 다루기 위해서라면 두 함수를 구현한 뒤 사용하면 좋을 것 같습니다.
4. 밑줄
파이썬을 사용하면서 protected와 private의 역할을 하는 것이 바로 밑줄이라는 말을 들은 적이 있습니다. 하지만 기본적으로 캡슐화의 개념보다 사용되지 않음을 표시하는 정도라는 점도 “파이썬 코딩의 기술”을 보고 공부 한 적이 있습니다.
실제로 자주 사용하지는 않았지만, 최근 오픈소스를 보면서 마음이 달라졌습니다. 그리고 단순한 _ 값의 사용이 자주 보였지만, 의미를 알지 못했는데 이 책을 읽고 알 수 있었습니다.
1. _var
이러한 형태는 어느정도 맞추면서 코드를 작성하고 있습니다. 앞에 접두사에 1개의 밑줄을 치면 내부와 하위 클래스등 에서만 사용 할 것이라는 표시가 됩니다.
여기서 중요한 점은 와일드카드를 통해 import하면 해당 값을 가졍 올 수 없다는 점입니다. 그 외에는 불러 올 수 있습니다.
2. var_
밑줄을 마지막에 추가하는 방법은 직관적으로 중복되지 않도록 변수 명을 설정하는 방법입니다.
3. __var
접두사로 붙는 _이 2개가 된다면 _var과는 다른 의미가 됩니다. Private을 표현한다고하는데 실제로 값을 캡슐화는 하지 않더라도 값의 메타데이터는 조금 바꿉니다.
class test:
def __init__(self):
self.__var = 1
def run(self):
print(self.__var)
t = test()
t.run()
# 1
t.__var
# AttributeError: 'test' object has no attribute '__var'
__var값을 실제로 가져오려고하면 에러가 발생합니다. 실제로 __var이 어떻게 저장되었는지 확인해봅시다.
print(t.__dict__)
# {'_test__var': 1}
앞에 클래스 이름이 붙어 있습니다. 이러한 성격을 이용해서 __는 변수명이 겹치지 않도록 도와줌과 동시에 외부에서 해당 값을 사용 할 때 직관적으로 사용 할 수 없도록 도와줍니다. 그래서 외부에서 원치 않게 변경하는 것을 방지합니다.
4. __var__
이런 형태는 대체로 파이썬 자체에서 특별한 의미를 갖는 함수들이 가지고 있는 이름입니다.
5. _
오픈소스를 보면 주로 많은 값이 이렇게 _만으로 되어 있는 경우가 있었는데, 딱히 실제로 사용되지 않는 변수나 임시적인 변수 명에 주로 사용합니다.
큰 의미를 갖지는 않지만, 오히려 의미가 없다는 의미로 _를 사용하는 것은 좋은 습관이라고 생각합니다.