-
Notifications
You must be signed in to change notification settings - Fork 2
2017 03 14 Python 스타일
krikit edited this page Mar 14, 2017
·
1 revision
- PEP8을 준수하고 커밋 전에 pylint로 점검하자.
- unicode literals, print function으로 python3 시대를 대비하자.
- Python은 언어 차원에서 스타일을 강제하진 않지만 (indentation만큼은 강제함) 표준 가이드라인이 있습니다.
- PEP8
- yum, apt-get, brew 등을 통해 설치해도 되고, pip를 통해 설치해도 됩니다.
- 다음과 같이 실행합니다.
$ pylint -rn your_python_code.py
No config file found, using default configuration
************* Module your_python_code
I:396, 0: Locally disabling global-statement (W0603) (locally-disabled)
I:564, 0: Locally disabling broad-except (W0703) (locally-disabled)
W:373, 0: TODO: configurable for a collection via file.cfg (fixme)
C: 1, 0: Too many lines in module (1459/1000) (too-many-lines)
R:918, 0: Too many local variables (16/15) (too-many-locals)
- "-rn" 옵션은 "--reports=n"와 같은데 마지막에 리포트를 출력하지 말라는 옵션입니다.
- 리포트 때문에 에러 메세지가 밀려 올라가 볼 수 없기 때문입니다.
- 첫 줄의 "No config file found, ..."와 같은 메세지는 설정 파일이 없어서 기본 설정으로 실행했다는 것입니다.
- 팀 혹은 프로젝트에서 사용하는 특별한 스타일이 있는 것이 아니라면 설정을 권장하지 않습니다.
- "I:396, ..."부터 한 라인에 하나의 에러 메세지를 보여줍니다.
- 메세지를 보면서 하나하나 잡으면 됩니다. ;)
- false alarm 혹은 도저히 어쩔 수 없는 경우 아래와 같이 suppress 합니다. (그래도 "I"와 같이 나옵니다.)
global _TRG_LOCK # pylint: disable=global-statement
- python2로 한글 텍스트를 다루다보면 unicode('가나다', 'UTF-8'), '가나다'.encode('UTF-8'), '가나다'.decode('UTF-8') 명령어를 왔다갔다 하며 머리를 쥐어뜯어 본 적이 있을겁니다.
- 그나마 가장 현실적인 해결책은 "파일 IO를 제외하고는 전부 유니코드를 사용하라"라는 idiom일 겁니다.
- python3에서는 '가나다'는 문자열이고 유니코드입니다. python2에서는 '가나다'는 문자열은 맞지만 byte array입니다. python3에서는 문자열(유니코드)과 byte array를 구분하고, byte array의 경우 명시적으로 b'가나다'와 같이 사용해야 합니다.
- 이렇게 python2에서 python3처럼 문자열을 기본적으로 유니코드를 사용하도록 하는 마법의 선언이 있습니다.
from __future__ import unicode_literals
- 그리고 유니코드와 관련된 참고할 만한 cat.py 프로그램입니다. (안심하세요 pythonic합니다. ;)
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
cat
__author__ = 'krikit ([email protected])'
__copyright__ = 'Just Copyleft! No right reserved.'
"""
###########
# imports #
###########
from __future__ import unicode_literals
from __future__ import print_function
import codecs
import logging
logging.basicConfig(level=logging.INFO)
import optparse
import sys
reload(sys)
sys.setdefaultencoding('UTF-8') # pylint: disable=no-member
########
# main #
########
def main():
"""
cat
"""
for line_num, line in enumerate(sys.stdin, start=1):
line = line.rstrip('\r\n')
logging.debug('%d: %s', line_num, line)
print(line)
if __name__ == '__main__':
_PARSER = optparse.OptionParser(description='cat')
_PARSER.add_option('--input', help='input file <default: stdin>', metavar='FILE')
_PARSER.add_option('--output', help='output file <default: stdout>', metavar='FILE')
_OPTS, _ = _PARSER.parse_args()
if _OPTS.input:
sys.stdin = codecs.open(_OPTS.input, 'rt', encoding='UTF-8')
if _OPTS.output:
sys.stdout = codecs.open(_OPTS.output, 'wt', encoding='UTF-8')
main()
- open('file.txt') 대신 codecs.open('file.txt', 'rt', ecoding='UTF-8')을 사용합니다.
- stdin, stdout으로 입축력 시 인코딩을 명시하기 위해 "export PYTHONIOENCODNG=UTF-8"이라고 환경 변수를 지정하거나, 위와 같이 "sys.setdefaultencoding('UTF-8')"이라고 코드에 명시해 줍니다.
- python2에서 print는 statement인 반면 python3에서는 하나의 함수입니다.
- python2에서 print 함수를 사용하기 위해서는 아래 마법의 선언이 있습니다.
from __future__ import print_function
- sys.stderr로 출력하고 싶어요.
# python 2
print >> sys.stderr, 'Hello World'
# python 3
print('Hello World', file=sys.stderr)
- 새 줄로 넘기지 않고 연달아 출력하고 싶어요.
# python 2
print 'Hello',
print 'World'
# python 3
print('Hello', end=' ')
print('World')