메일 프로그램을 하나 짜야 하는데 클래스 상속과 재정의 문제로 반나절 삽질을 했습니다.

현재 서버에 설치된 SMTPd가 localhost조차도 인증을 해야만 메일을 보낼 수 있게 설정되어 있습니다. smtplib 모듈의 login(user, password) 메쏘드를 이용하면 된다는 말을 듣고 그대로 해보았는데 계속 실패하는 것입니다.

문제의 원인을 찾아본 결과, SMTPd가 제공(한다고 표시)하는 AUTH 방식이 제대로 작동하지 않는 것이었습니다. 위 SMTPd의 ehlo 메시지는 다음과 같습니다.

코드:
ehlo localhost
250-xxx.xxx.co.kr
250-PIPELINING
250-AUTH LOGIN CRAM-MD5 PLAIN
250 8BITMIME


LOGIN, CRAM-MD5, PLAIN 이 3가지의 인증방식을 제공한다고 나와 있지만, 실제로 제가 테스트해본 결과 CRAM-MD5 인증은 작동하지 않습니다. 그동안 몰랐던 이유는 아웃룩이나 모질라에서는 LOGIN 방식만을 지원하기 때문에 메일 클라이언트에서 메일 보내고 받는 데 여태 문제가 없었기 때문입니다. 물론 CRAM-MD5 인증방식이 제대로 작동하도록 재설치하면 아무 문제가 없지만, 그럴 수 없는 사정이었습니다.

smtplib 모듈의 login() 메쏘드 소스를 보니, 서버의 AUTH 응답 코드를 리스트로 가지고 있다가, CRAM-MD5, LOGIN, PLAIN 순서대로 인증 시도를 하더군요.

코드:
if authmethod==AUTH_CRAM_MD5:
    ...
elif authmethod==AUTH_LOGIN:
    ...
elif authmethod==AUTH_PLAIN:
    ...


여기서 문제가 생기는 것입니다. 실제로 서버에서는 CRAM-MD5 인증방식이 제대로 작동하지 않는데도 불구하고 Response 메시지에 표시가 되는 문제가 있는데, smtplib 모듈에서는 Response 메시지만을 읽고 CRAM-MD5 방식의 인증을 먼저 시도한다는 거죠. 참고로 CRAM-MD5 인코딩은 서버측 세션값과 timestamp, 클라이언트의 MAC 어드레스 등을 base64로 인코딩합니다. 이에 비하자면 LOGIN은

코드:
"%s %s" % ('LOGIN', encode_base64(user, eol=""))


어렵지 않게 풀립니다. 아웃룩, 모질라 등의 메이저 메일 클라이언트들에서 CRAM-MD5 방식의 SMTP 인증을 빨리 지원해주기를 바랍니다. (사실 위 클라이언트들에서 CRAM-MD5 방식을 (smtplib 모듈과 같은 방식으로) 지원했더라면, 서버 관리자가 진작에 문제를 알아차렸을 것이므로 이렇게 허망한 삽질을 할 이유도 없었을 것입니다. -_-)

아뭏든 smtplib.py 소스에 직접 손을 대면 어렵지 않게 해결할 수 있었겠지만--if/elif 순서를 바꿔 LOGIN을 먼저 처리하도록--, 표준 라이브러리에 손을 대는 것이 영 찜찜하여, 관계된 모듈의 클래스를 상속받아 문제가 되는 login() 메쏘드만 재정의했습니다.

코드:
import smtplib

class SimpleSMTP(smtplib.SMTP):
    def login(self, user, password):
        (code, resp) = self.docmd("AUTH",
            "%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))
        if code != 334:
            raise SMTPAuthenticationError(code, resp)
        (code, resp) = self.docmd(encode_base64(password, eol=""))
        if code not in [235, 503]:
            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)


아래와 같이 사용합니다.

코드:
    smtp = SimpleSMTP(smtphost)
    smtp.login(user, password)
    smtp.sendmail(mailfrom, mailto, subject+'\r\n\r\n'+body)
    smtp.quit()


혹시 SMTP 인증 문제로 어려움을 겪고 계시다면, 을 참조하여 서버와 주고받는 메시지를 확인해보시고, smtplib 모듈에서 encode_base64, encode_cram_md5, encode_plain 등을 각각 추출하여 직접 서버와 통신해보십시요.

코드:
def encode_base64(s, eol=None):
    return "".join(base64.encodestring(s).split("\n"))

def encode_cram_md5(challenge, user, password):
    challenge = base64.decodestring(challenge)
    response = user + " " + hmac.HMAC(password, challenge).hexdigest()
    return encode_base64(response, eol="")

def encode_plain(user, password):
    return encode_base64("%s\0%s\0%s" % (user, user, password), eol="")

 

 

출처 : http://bbs.python.or.kr/viewtopic.php?t=19659

'programming > python' 카테고리의 다른 글

파이썬 코딩 스타일 가이드  (0) 2004.01.27
파이썬 스타일 지도서  (0) 2004.01.27
특정 달의 날짜 수 구하기  (4) 2004.01.27

파이썬 코딩 스타일 가이드

한글판 johnsonj 2003.11.21

파이썬 코드의 형식에는 수 많은 방식이 있다. 이런 자유를 남용하여 읽기 어렵게 만들고 그리하여 유지보수하기가 힘들게 코드를 작성하는 프로그래머가 많다. 적절하게 코드를 포맷하는 방법에는 여러가기 있겠지만, 여기에서는 실제로 사용할 때 쓸모가 있을 만한 가이드라인을 제공한다. 맹목적으로 따를 필요는 없지만, 어설픈 형식에는 확실하게 어깃장을 놓아볼 생각이다. 이 가이드라인중 일부는 크게 쓸모가 없어 보일 수도 있지만, 코드를 읽어 보면, 확실하게 그 차이를 느낄 수 있을 것이다.

다음에서, 각 항목은 설명다음에 그에 관련된 코드가 따른다. 이 코드로 문제를 지적하면서 코드를 교정하겠다. 항목에 코드를 짝짓는 일은 여러분의 책임이다. 모쪼록 이렇게 해서 재미있게 이 스타일 가이드를 읽기를 바란다:-) 일반적으로, 한 섹션에서 앞의 항목은 뒤의 항목보다 더 중요하며 그리고 더 자주 일어나는 에러를 나타낸다.

또, 가장 단순한 스타일의 실수를 잡는 것을 돕기 위하여 자동화된 스타일 점검기 프로그램을 제공한다. 이 프로그램은 에러 모두를 잡아내는 것은 아니지만, 일반적인 에러들을 많이 잡아낸다. 코드를 제출하려면 먼저 스타일 점검기에 그 코드를 넣어 테스트해 볼 필요가 있을 것이다; 실패하면, (스타일 점검기에 버그가 있다는 것을 확신시켜 주지 못하는 한, 물론 그럴 수 있다) 평가 대상이 되지 못한다. 파이썬 스타일 점검기는 (물론) 파이썬으로 작성되었다;-). 먼저 내려 받은 다음, "~/bin" 디렉토리에 넣고 나서 (디렉토리를 하나 만들고 탐색 경로에 넣어두면 된다) 다음과 같이 하자:

    chmod +x ~/bin/python_style_check
그 다음에, 파일 "foo.py"의 스타일을 점검하려면, 다음과 같이 한다:
    python_style_check foo.py
에러가 많이 보고되더라도 놀라지 말자; 그냥 파일을 찾아 들어가 고치면 된다. 어떤 줄에서는 갖가지 모습으로 규칙을 범하고 있을 것이다; 그 모든 실수들을 고쳐야 한다. 처음에는 이 프로그램이 마음에 들지 않겠지만, 그 결과로 코드가 훨씬 읽기에 편하게 된다는 사실을 명심하자. 프로그램에서 버그를 발견했다고 생각하면, 즉시 알려주기를 바란다; 이 프로그램은 개발중인 작품이다. 주의할 것은 스타일 점검기가 가끔씩 멍청해서 주석이나 기호문자 문자열 안에 있는지 알지 못하므로, 그러한 경우에는 실제로는 에러가 아닌데도 보고하는 경우가 있다. 그렇다면, 그냥 무시하면 된다. 스타일 점검기는 또한 여러 자바 소스 코드 파일도 다룰 수 있다는 것을 주목하자. 그래서 따로따로 파일을 지정하는 대신에 다음과 같이 할 수 있다:
    % python_style_check *.py
물론, 파일이 .py로 끝나지 않으면 따로따로 다 지정해야 한다.


일반적으로 많이 저지르는 스타일 실수

다음에 지적하는 실수들은 거의 보편적이라고 할 정도로 아주 자주 일어난다. 그러므로, 특히 주의해서 피해 주기를 바란다. 링크를 따라가서 아래에 기술된 설명을 보도록 하자. 별표(*)가 뒤에 붙은 스타일 실수는 스타일 점검기로 잡을 수 있다.
  • TABS*   코드에 탭 문자를 사용한다.
  • OPERATOR_SPACE*   연산자 양쪽에 공간을 하나씩 두지 않는다.
  • COMMA_SPACE*   쉼표 뒤에 공간을 두지 않는다.
  • LINE_LENGTH*   78 문자가 넘는 줄을 작성한다.
  • USAGE_STMT   사용 설명이 빠졌거나 부적절하다.
  • BLANK_LINES   함수나 프로그램에 너무 많은 또는 너무 적은 빈 줄을 사용한다.
  • COMMENTS_FULL_SENTENCES   불완전한 문장으로 주석을 작성한다.
  • COMMENTS_GRAMMATICAL   문법적으로 옳지 않거나 철자가 바르지 못한 주석을 작성한다.
  • COMMENT_SPACE*   열림-주석 심볼 "/*" 뒤에 닫힘-주석 심볼 "*/" 앞에 공간을 하나씩 두지 않는다.
  • DOCSTRINGS   함수, 클래스, 혹은 모듈의 머리부에 적절한 문서화문자열 주석을 작성하지 않는다.
  • EXCEPTIONS_CATCH_ALL   일망타진(catch-all) 예외 처리를 사용한다.

스타일 실수의 범주

일반

  • [TABS]

    절대로 탭 문자(ascii 0x9)는 사용하지 말자! 사람마다 탭 설정을 다르게 사용한다. 너비가 2인 탭으로 잘 작동하는 듯 보이는 코드라도 너비가 8인 탭에서는 문제가 된다. (추천해 마지 않는) 이맥스를 사용한다면, 다음 줄들을 .emacs 파일에 넣어두자:

        ;; Load python mode.  The path will depend on the installation.    (load-file "/home/cs11/emacs/python-mode.el")    ;; Make files that end in .py automatically go into python mode.    ;; If your file doesn't end in ".py" then you'll have to do    ;; "M-x python-mode" manually after you load up the file.    (append '(("\\.py\\'" . python-mode)) auto-mode-alist)    ;; Set up initialization parameters for python mode:    (setq python-mode-hook          '(lambda () (progn                        (set-variable 'py-indent-offset 4)                        (set-variable 'py-smart-indentation nil)                        (set-variable 'indent-tabs-mode nil) )))
    이맥스에서 파이썬 코드를 편집하면서 탭 키를 치면, 자동으로 그 코드를 그 줄에서 합리적인 위치까지 들여쓰기 해 준다. 앞의 코드를 (이 코드는 emacs-lisp 코드이지만, 신경쓰지 말것) .emacs 파일 안에 넣어 두면, 탭 키를 치더라도 실제로 코드에 탭 문자가 들어가는 대신에, 그냥 네 개의 공간을 넣는다.

  • [OPERATOR_SPACE]

    언제나 다음 연산자들 주위에는 각 양쪽에 공간을 하나 두자: 할당 연산자 (=, +=, 등등), 비교 연산자 (==, <, >, !=, <>, <=, >=, in, not in, is, is not), 불리언 연산자 (and, or, not), 그리고 산술 연산자. 예제:

    i = j + 1               # 불가 i=j+1        submitted += 1          # 불가 submitted+=1        x = x * 2 - 1           # 불가 x=x*2-1        hypot2 = x * x + y * y  # 불가 hypot2=x*x+y*y        c = (a + b) * (a - b)   # 불가 c=(a+b)*(a-b)

    어떤 사람들은 * 또는 / 양쪽에 공간을 두지 않는 편을 더 좋아하지만, + 그리고 -에는 우선순위에 대한 힌트로서 공간을 두기를 좋아한다. 그렇지만 이는 권장할 수 없다. 그렇지만, 간단한 증/감 연산에 대한 배열 첨자에서는 양쪽에 공간을 생략해도 좋다:

        b = a[i-1]

    불행하게도 현재 버전의 스타일 점검기는 무조건 이에 표식을 한다.

  • [COMMA_SPACE]

    쉼표 다음에는 언제나 공간을 하나 두자.

  • [LINE_LENGTH]

    주변에는 여전히 80개의 문자로 제한되는 장치들이 많다 (특히 프린터). 그런 장치에 대하여 기본 줄바꿈 값은 보기에 않 좋다. 그러므로, 줄들을 모두 78 자까지 제한하자.

    긴 줄을 감싸는 유력한 방법은 파이썬이 활괄호, 각괄호, 반괄호 안에서는 묵시적으로 줄이 연속되어 있다고 간주하는 점을 이용하는 것이다. 필요하다면, 표현식 주위에 괄호를 하나 더 덧붙여도 좋지만, 역사선을 이용하는 것이 더 보기 좋은 경우도 있다. 반드시 연속된 줄을 적절하게 들여쓰기 하자. 예제 약간:

        class Rectangle(Blob):        def __init__(self, width, height,                     color='black', emphasis=None, highlight=0):            if width == 0 and height == 0 \               and color == 'red' and emphasis == 'strong' \               or highlight > 100:                raise ValueError, "sorry, you lose"            if width == 0 and height == 0 and (color == 'red' \                                               or emphasis is None):                raise ValueError, "I don't think so"            Blob.__init__(self, width, height,                          color, emphasis, highlight)

    어떤 경우에는, 명시적인 줄 연속 문자가 불필요한 경우가 있다. 잘 모르겠으면, 어쨌거나 사용하자. 또, 기다란 불리언 표현식에는 (a and b and c...) "and" 또는 "or"를 줄의 끝이 아니라 앞에다 두자; 이렇게 하면 표현식이 앞의 줄에서 계속된다는 사실을 확실히 알 수 있다.

  • [USAGE_STMT]

    프로그램이 올바르지 않은 인자로 호출되면, 그 사실을 탐지해서 터미날에 사용법을 인쇄해 주어야 한다. 사용 방법에는 반드시 그 프로그램의 이름이 들어가야 한다. 가장 쉽게 하는 방법은 sys.argv[0]를 이용하는 것이다.

        import sys, re    # 완전한 프로그램의 경로이름을 벗겨내고 프로그램 이름만 남긴다.    prog_name = re.sub(".*/", "", sys.argv[0])    usage = "usage: %s input_filename output_filename" % prog_name    if len(sys.argv) != 2:       print usage       sys.exit(1)
    주목할 것은 인자들이 연상작용을 돕는 이름이 있다는 것이다. 사용법 메시지가 아주 길면, 문서화문자열 안에 넣자 (아래 참조).

  • [BLANK_LINES]

    최고-수준의 함수와 클래스 정의는 최소한 두 개의 빈 줄로 가르자. 클래스 안에서 메쏘드 정의를 가르는 것도 역시 빈 줄 두개로 가른다. 그러나 어떤 경우에는 빈 줄 한개도 괜찮다. 관련 함수를 모아 놓은 그룹이라면 빈 줄을 더 사용하여도 좋다 (그러나 너무 지나치면 안된다). 또 주석을 두어 함수의 그룹을 갈라도 좋다. 예.

        # 다음 함수들은 위젯 클래스를 위하여 인터넷 접근을 제공한다.

    정말로 중요한 섹션이라면, 또는 클래스 머리부라면, 다음과 같이 하자:

        #    # 이 클래스 위젯이 구현하는 객체는    # 갖가지 종류의 일들을 할 수 있다.    #

    즉. 즉 머리부의 윗쪽과 아래쪽에 빈 주석 줄 하나씩을 두자.

    기다란 함수나, 또는 함수 안에서 섹션이 길다면, 주석을 함수/블록의 끝에다 다른 것도 좋은 생각이다, 예.

        def foobar(x, y, z):        # 다음에 코드가 2000 줄 따른다...        return 1    # foobar 끝	

    비슷하게, "# end if", "# end while", 등등을 두어도 좋다. 더 좋은 해결책은 이것이 필요하지 않도록 가능하면 함수와 블록을 짧게 유지하는 것이다.

    함수에서 논리적 구획을 나타내려면 빈 줄들을 사용하자. 또한 각 if/while/for 서술문 앞에다 빈 줄들을 두어서 그를 둘러싼 코드와 논리적으로 구별하기를 즐기는데, 경험상 이렇게 하면 코드가 더 읽기 쉽다.

    코드에서 서로다른 구역을 분별할 필요가 확실하지 않는 한 코드 구역 사이에 너무 많은 빈줄(> 2)을 놓지 말자.

  • [INDENT_CONSISTENT]

    들여쓰기 수준은 일관성이 있어야 한다. 한 수준 들여쓰기에 4개의 공간을 선호한다.

  • [MAGIC_NUMBER]

    둘러싼 코드와 별 관련이 없는 기다란 숫자를 파일에 넣는 것을 피하자. 이는 "마법의 수(magic number)"라고 알려져 있다 (역주 : 물리학 용어에서 유래, 양성자의 수 또는 중성자의 수가 미리 정해진 어떤 값을 가지면 원자핵이 특별히 안정된다. 그렇지만 처음 관찰되었을 때는 왜 그런지 잘 설명할 수가 없어서 그런 수를 마법의 수(magic number) 라고 불렀다. 마법의 수를 가지면 존재 확률이 높아짐을 비유해서, 각종 프로토콜에서 서로 간에 신분을 확인하는 숫자를 마법의 수라고 일컫는다.) 대신에 그 마법의 수를 파일의 위에다 정의해 두자.

  • [USELESS_CODE]

    아무 기능이나 효과도 없는 코드를 넣지 말자. 그것이 디버깅 코드라면, 확실하게 그렇다고 표식을 해 두어야 한다.

  • [STMTS_ON_LINE]

    한 줄에 여러 서술문을 두지 말자. 아주 간단한 서술문이라고 할지라도 안된다. 그저 혼란스럽고 읽기가 어렵게 만들 뿐이다. 비슷하게, 다음도 별로 마음에 안든다:

        if not line: break

    그 보다 다음을 더 선호한다:

        if not line:        break

    명심하자: 새줄문자(newlines)에는 세금이 없다. 한 줄에다가 억지로 많이 구겨 넣으려고 하지 말자.

  • [BAD WHITESPACE]

    다음의 장소에는 공백(whitespace)을 사용하지 말자:

    • 활괄호, 각괄호, 또는 반괄호 바로 안쪽에서, 다음과 같이:
          spam( ham[ 1 ], { eggs: 2 } )

      언제나 다음과 같이 작성하자:

          spam(ham[1], {eggs: 2})
    • 쌍점, 쌍반점, 또는 쉼표 바로 앞에서, 다음과 같이:
          if x == 4 :        print x , y        x , y = y , x

      언제나 다음과 같이 작성하자:

          if x == 4:        print x, y        x, y = y, x
    • 함수 호출의 인자 목록을 시작하는 여는 괄호 바로 앞에서, 다음과 같이
          spam (1)

      언제나 다음과 같이 작성하자

          spam(1)
    • 지표화나 조각썰기를 시작하는 여는 괄호 바로 앞에서, 다음과 같이:
          dict ['key'] = list [index]

      언제나 다음과 같이 작성하자

          dict['key'] = list[index].
    • 다른 것과 줄을 맞추기 위해 할당 (또는 다른) 연산자 주위에 과도한 양의 공간, 예를 들어:
          x             = 1    y             = 2    long_variable = 3

      최고로 좋은 규칙: 연산자를 8개 또는 9개의 공간을 두고 이동해야 한다면, 시간을 낭비하지 말자. 그렇지 않으면, 정렬하자. 예., 다음은:

          x = 1    foo = 2    fudge = 5

      다음과 같이 바꾸자.

          x     = 1    foo   = 2    fudge = 5

      그러나 다음은

          x = 1    y = 2    this_variable_name_is_really_long = 3

      그대로 두자. 이는 스스로 내려야 하는 결단(judgment call)의 문제이다.

  • [KEYWORD_SPACES]

    '='가 키워드 인수나 기본 매개변수 값을 나타내는데 사용되면 '=' 주위에 공간을 사용하지 말자. 예를 들면:

        def complex(real, imag=0.0):        return magic(r=real, i=imag)
  • [PRECEDENCE]

    모든 경우에 덧셈/뺄셈과 할당 서술문 보다 곱셈/나눗셈이 우선순위가 있음을 괄호로 둘러 연산자 우선순위를 나타내자.

  • [IMPORT]

    일반적으로, "from X import *"로 형태로 사용하는 것을 피하자; 다음과 같이 하든가:

        from X import Y  # 많이 사용되는 함수만 하나 수입

    또는 다음과 같이 하자:

        import X # 사용할 모듈에서 수 많은 함수가 필요할 때.

    또, 클래스나 함수 안에서 "import X"나 "from X import Y"를 사용하지 말자. 꼭 그렇게 사용해야 할 경우를 보지 못했고, 그렇게 하는 것은 혼란만 초래할 뿐이다. 모든 수입 서술문은 모듈의 최상위 수준에 그리고 파일의 최상단에 두자. 그렇게 해 두어야, 어디에서 찾아 보아야 할지 알 수 있다. 어떻게 형식화할지는 자신의 자유이다

        import X, Y, Z

    또는

        import X    import Y    import Z

    보통 한 번 쓰고 버릴 스크립트에는 앞의 형식을 커다란 프로젝트에는 뒤의 형식을 사용하는 경향이 있다.

주석

  • [COMMENTS_FULL_SENTENCES]

    주석이 구이거나 문장이라면, 소문자로 시작하는 식별자가 아닌 한 첫 단어는 반드시 대문자여야 한다 (식별자의 격을 절대로 바꾸지 말 것!). 되도록 완벽한 문장이면 더 좋다. 마침표 뒤에는 공간을 두 개 사용해야 한다. 이상적으로, 식별자를 가리키려면 따옴표를 두르자, 예.

        # 변수 'nitems'은 스택에 있는 항목의 개수를 나타낸다.

    주석이 아주 짧다면, 완전한 문장이 될 필요가 없으며, 또는 마침표로 끝날 필요가 없다 예.

        i = 1  # 회돌이 지표
    이는 이른바 "인라인 주석(inline comment)"이라고 부른다. 무언가를 기술할 때만 이를 사용하자. 즉, 위의 코드 조각에서 "변수 'i'는 회돌이 지표를 나타낸다"와 같이 말할 때만 사용하자.

  • [COMMENT_GRAMMATICAL]

    주석은 올바르게 철자가 되어야 한다 (오타 불가) 그리고 문법적으로 옳아야 한다. 고등하고 영어 선생님처럼 굴고자 하는 것이 아니라, 철자도 틀리고 문법도 안 맞고 게다가 오타까지 있는 주석을 읽는 것은 정말로 불쾌한 일이다.

  • [COMMENT_SPACE]

    여는-주석 사인 뒤에는 늘 공간을 남겨두자 예.

        # 이 주석을 읽기 쉽다.    #이 주석은 읽기 어렵다

  • [COMMENT_NON_OBVIOUS]

    정황(context)으로 미루어 완전히 짐작하기 어려운 것이면 모두 주석을 달자. 특히, 사용중인 코드나 알고리즘이 꼼수적이라면 무조건 주석을 달자. 또 각 함수의 시작부에 함수가 무슨 일을 하는지 기술하는 주석을 달자. 의심스러우면, 가능한한 주석을 달자.

  • [COMMENT_REDUNDANT]

    너무나 당연한 것은 다시 주석을 달면 안된다. 이는 특히 인라인 주석에 흔하다. 예제:

        x = x + 1   # x를 증가시킨다
  • [COMMENT_MEANINGLESS]

    의미없는 주석은 달지 않는다 예.

        i = 1   # i
    웃지 말것; 실제로 이런 것들을 본 적이 있다.

  • [COMMENTS_CONSISTENT_WITH_CODE]

    코드와 모순되는 주석은 달지 않는 만 못하다. "코드가 변경되면 언제나 최우선으로 주석을 최신으로 유지하자!"

  • [COMMENT_INDENT]

    언제나 둘러싼 코드 만큼 같은 정도로 코드를 들여쓰자.

  • [COMMENT_INLINE]

    편의를 위해 인라인 주석을 되도록이면 정렬하자. 다른 말로 하면, 다음과 같이 하면 안 되고:

        x = x + 1       # x에 대한 멋진 주석    y = y + 1   # y에 대한 멋진 주석
    대신에, 다음과 같이 하자:
        x = x + 1       # x에 대한 멋진 주석    y = y + 1       # y에 대한 멋진 주석

  • [COMMENT_PRECEDING]

    피할 수만 있다면 앞의 코드에 적용되는 주석을 달지 말자. 현재 코드 줄이나 또는 바로 다음에 따라오는 코드 줄들을 가리키는 주석을 달려고 노력하자.

  • [COMMENT_BLOCK]

    블록 주석은 일반적으로 뒤에 따르는 코드의 일부 (또는 모두)에 적용된다. 그리고 그 코드와 같은 수준으로 들여쓰기 된다. (주석 안에서 들여쓰기된 텍스트가 아닌 한) 블록 주석의 각 줄은 #와 공간 한개로 시작한다. 블록 주석 안에서 문단은 한 개의 #를 담은 줄로 갈라진다. 블록 주석은 위와 아래에 빈 줄이 있으면 아주 좋다 (또는 새로운 함수 정의의 섹션이 시작되는 곳에 위치한 블록 주석이라면 위에 두 줄 그리고 아래에 한 줄도 좋다). 한개의 #를 가진 줄 하나로 블록 주석을 시작하고 끝내면 좋다; 이는 개인적인 선호의 문제이다. 다른 말로 하면, 블록 주석은 다음과 같이 보인다:

        #    # 빈 줄 다음에 첫 줄이 온다.    #    # 각 문단은 또 빈 줄로 갈라진다,    # 그리고 끝에는 빈 줄이 하나 있다.    #
    클래스나 함수 시작 또는 파일의 상단에 놓인 블록 주석은 반드시 문서화문자열이 되어야 한다 (아래 참고).

문서화 문자열

  • [DOCSTRINGS]

    모든 모듈은 일반적으로 문서화문자열이 있어야 한다. 그리고 모듈에 수출된 모든 함수와 클래스도 역시 문서화 문자열이 있어야 한다. (__init__ 구성자를 비롯하여) 공개 메쏘드 또한 문서화 문자열이 있어야 한다. 잘 모르겠으면, 문서화 문자열을 모든 함수에 덧붙이자. 그렇지 않으면, 어쨌든 함수의 목적을 나타내는 주석을 달아야 한다. 그러므로 문서화문자열을 덧붙이지 않을 까닭이 없다.

    (독립-실행 프로그램인) 스크립트의 문서화문자열은 반드시 그의 "사용방법" 메시지가 사용이 가능하여 하며, 스크립트가 그릇된 인자로 혹은 인자가 없이 호출되면 인쇄되어야 한다 (위 참고).

    일관성을 위하여, 언제나 문서화문자열 주위에는 """삼중 겹 따옴표"""를 사용하자. 이렇게 하면 문서화 문자열을 여러 줄에 걸쳐 넣을 수 있다.

함수

  • [FUNCTION_DECOMPOSITION]

    주저하지 말고 함수를 적절한 곳마다 수 많은 자잘한 함수로 분해하자. 길이가 페이지를 넘어가는 함수는 작성하지 말자.

예외 처리

  • [EXCEPTIONS_CATCH_ALL]

    Don't do this:

        try:        # 코드는 여기에 둔다    except: # 모든 예외를 잡는다        pass

    현재 상황에 딱맞는 에러 처리 코드를 구현할 생각이지만, 당장은 그렇게 하고 싶지 않다면, 다음과 같이 작성하자.

        try:        # 여기에 코드를 둔다    except:  # 예외를 모두 잡는다        raise  # 잡은 예외를 다시 일으킨다

    이 모듈의 코드가 늘어나면 그 때 에러를 잡아 일반적인 방식으로 처리하자. 더 좋은 방법은, 각 예외에 대하여 따로따로 이렇게 하고 그리고 나중에 이를 고치면 얻는 효과에 대하여 주석을 다는 것이다:

        try:        # 여기에 코드를 둔다    except FooError:        # 수정요망(FIXME): 나중에 적절한 에러 처리를 구현할 것.        raise FooError # 해당 예외를 다시 일으킨다

    에러를 전혀 다루고 싶지 않다면, 절대로 안에다 'try: except:' 조건을 두지 말고, 나중을 위해 주석을 붙여 두자:

        # 수정요망(FIXME): 함수 bar()가 일으키는 FooError를 잡을 것.


 

출처 : http://home.hanmir.com/~johnsonj/etc/CS%2011%20Python%20track%20coding%20style%20guide.htm

'programming > python' 카테고리의 다른 글

SMTP 인증에 관한 팁  (0) 2004.01.28
파이썬 스타일 지도서  (0) 2004.01.27
특정 달의 날짜 수 구하기  (4) 2004.01.27

기본이 되는 내용이라고 할 수 있을거 같네요.

---------------------------------------------------

 

파이썬 스타일 지도서

Author: Guido van Rossum
translated into korean by johnsonj

 

XXX 서문.

바보같은 일관성은 골치거리이다.

스타일 지도서는 일관성에 관한 것이다. 이러한 스타일 지도서의 일관성은 중요하다. 프로젝트를 수행중일때는 더 중요하다. 하나의 모듈 혹은 함수안에서의 일관성은 더욱 중요하다.

그러나 대단히 중요한 것은 : 비일관적(inconsistent)이어야 할 때를 알도록 하라 -- 때때로 스타일 지도서는 단순히 적용되지 않는다. 의심스러울 경우에는, 여러분 자신이 최선의 판단을 하라. 다른 예들을 살펴보고 어떤 것이 가장 훌륭하게 보이는 지를 결정하라. 그리고 묻기를 주저 하지 마라!

차 례

  • 전체보기 -- 탭, 공백, 그리고 새로운 라인을 사용하는 법.
  • 주 석 -- 주석을 (그리고 문서화 문자열들을) 적절히 사용하는 법에 관하여.
  • 이 름 -- 다양한 이름짓기의 관례들.

전체보기

XXX 들어가기.

들여쓰기

Emacs의 파이썬 모드의 기본값을 사용하라: 한개의 들여쓰기 레벨당 4개의 공백을.
여러분이 혼란스럽지 않도록 진짜로 오래된 코드들에 대해서는 여러분은 8개 공백의 탭을 계속 사용할 수 있다.
Emacs의 파이썬 모드는 하나의 파일에 가장 많이 사용되는 들여쓰기 수준을 자동적으로 탐지해서 들여쓰기 매개변수를 그에 맞추어 설정한다.

탭인가 공백인가?

절대로 탭과 공백을 혼용하지 마라.
파이썬에서 가장 인기 있는 들여쓰기는 공백만을 사용하는 것이다. 두번째로 인기 있는 방법은 탭만을 사용하는 것이다.
탭과 공백을 혼용하여 들여쓰기된 코드는 공백만을 단독으로 사용하여 변환되어야만 한다.(Emacs에서는, 전체 버퍼를 선택하여 ESC-x를 쳐서 탭문자들을 없애라.)

-t 옵션으로 파이썬 명령어 해석기에 요청하면, 탭과 공백을 불법적으로 혼용한 코드에 대하여 경고를 보낸다. -tt 옵션을 사용하면 이러한 경고는 에러가 된다. 이러한 옵션들을 강력히 추천한다!

라인의 최대 길이

라인당 80자 언저리로 제한된 장치들이 여전히 많이 있다. 그러한 장치들에 대하여 기본으로 지정된 자동 줄넘기기는 보기에 흉하다. 그러므로, 모든 라인을 최대 79 문자로 한정하라(Emacs는 라인을 정확히 80자 길이에서 자동 줄넘기기를 한다.)

기다란 라인을 자동으로 줄넘기기에 선호되는 방법은 괄호, 각괄호, 대괄호안에서 파이썬의 묵시적인 라인의 연속을 이용하는 것이다. 필요하다면, 표현식 주위에 여분의 괄호 한쌍을 추가할 수도 있다, 그러나 어떤 때는 백슬래쉬를 사용하는 것이 더 좋게 보일 때도 있다. 연속된 라인을 적절히 확실하게 들여쓰기하라.
Emacs의 파이썬 모드는 이것을 정확히 수행한다. 약간의 예를 들면:

class Rectangle(Blob):    def __init__(self, width, height,                 color='black', emphasis=None, highlight=0):        if width == 0 and height == 0 and \           color == 'red' and emphasis == 'strong' or \           highlight > 100:            raise ValueError, "sorry, you lose"        if width == 0 and height == 0 and (color == 'red' or                                           emphasis is None):            raise ValueError, "I don't think so"        Blob.__init__(self, widt, height,                      color, emphasis, highlight)

공백 라인들

최상위 함수와 클래스 정의는 두개의 공백 라인으로 분리하라. 한 클래스 안에서의 메쏘드 정의는 한개의 공백라인으로 분리된다. 여분의 공백라인은 관련된 함수들의 그룹들을 분리하는데 (아주 가끔) 이용되기도 한다. 공백라인은 한무리의 관련된 한라인 짜리 명령어 (예 : 일단의 비실행명령어)사이에서는 생략되기도 한다.

공백라인을 사용하어 메쏘드 정의를 가른다면, 'class'라인과 그 첫 번째 메쏘드 정의사이에 역시 하나의 공백라인을 둔다.

논리적 구별을 나타내기 위해서 함수에는 공백라인을, 아주 아껴서, 사용하라.

표현식과 서술문에서의 공백

신경쓰이는 것들

나는 다음과 같은 위치에서 공백문자를 사용하는 것을 아주 싫어한다 :

  • 괄호, 각괄호 또는 대괄호 바로 안쪽 예를 들어: spam(ham[ 1 ], { eggs: 2 } ).
    이것을 항상 다음과 같이 쓴다 :spam(ham[1], {eggs: 2}).
  • 컴마, 혹은 콜론, 세미콜론 바로 앞 예를 들어: if x == 4 : print x , y ; x , y = y , x.
    이것을 항상 다음과 같이 쓴다 : if x == 4: print x, y; x, y = y, x.
  • 한 함수의 호출때 사용되는 인수리스트를 감싸는 왼괄호 바로 앞 예를 들어spam (1).
    이것을 항상 다음과 같이 쓴다 spam(1).
  • 지표화나 썰기를 시작하는 왼괄호 바로 앞 예를 들어: dict ['key'] = list [index].
    이것을 항상 다음과 같이 쓴다 dict['key'] = list[index].
  • 다른 것 들과 맞추어 정렬하기 위하여 할당(혹은 다른) 연산자의 주위에 하나 이상의 공백을 두는 것 예 :
    x             = 1y             = 2long_variable = 3

    이것을 항상 다음과 같이 쓴다

    x = 1y = 2long_variable = 3

(위의 어떤 사항에 대해서도 나와 논쟁하려고 괴롭히지 마라 -- 나는 이미 15년간이나 이 스타일에 익숙해져 왔다.)

다른 추천사항

  • 이진 연산자들은 양쪽에 한개의 공백으로 항상 두룬다 : 할당(=), 비교 (==, <, >, !=, <>, <=, >=, in, not in, is, is not), 불리언값(and, or, not).
  • 수학적 연산자둘레에 공백을 삽입하는 것은 여러분이 판단하라. 항상 일관성있게 이진 연산자의 양쪽에는 공백이 있어야 한다. 약간의 예를 들면 :
    i = i+1submitted = submitted + 1x = x*2 - 1hypot2 = x*x + y*yc = (a+b) * (a-b)c = (a + b) * (a - b)
  • '='이 키워드 인수 혹은 기본 매변수값을 나타낼때 사용된다면 그 둘레에는 공백을 사용하지 마라.
    예를 들어 :
    def complex(real, imag=0.0):    return magic(r=real, i=imag)

주 석

코드에 배치되는 주석은 주석이 없는 것보다도 더 나쁘다. 코드가 변하면 항상 주석을 최신으로 먼저 유지하려는 노력을 하라!

주석이 구절이거나 문장이라면, 소문자로 시작하는 식별자가 아닌한 (절대로 식별자의 대소문자를 변경하지 마라!), 그것의 첫번째 단어는 반드시 대문자로 되어야 한다.

주석이 짧다면, 마지막의 구두점은 생략되는 편이 좋다. 블록 주석은 일반적으로 완전한 문장으로 이루어진 한개 혹은 그 이상의 문단들로 구성된다. 그리고 각 문장은 반드시 구두점으로 끝나야 한다.

여러분은 한 문장을 끝내는 구두점 다음에 두개의 공백을 사용할 수 있다.
영어를 쓸데처럼 언제나, 자신있게 공백을 적용하라.

영어를 사용하지 않는 나라의 파이썬 작성자들:
여러분의 언어을 사용하지 않는 사람들이 절대로 읽지 않을 것이라고 120% 확신하지 않는한, 영어로 주석을 작성하라.

블록 주석

블록 주석은 일반적으로 약간의 코드의 (또는 모두) 앞에 적용한다, 그리고 그 코드와 동일한 레벨에서 들여쓰기를 한다. 블록 주석의 각 라인은 (그것이 주석 안쪽의 들여쓰기된 텍스트가 아닌한) #와 한개의 공백으로 시작한다.
블록 주석안의 문단은 한개의 #을 포함한 공백라인으로 분리한다. 블록 주석은 위쪽 아래쪽으로 각각 한개의 공백 라인으로 둘려 싸여지는 것이 가장 좋다 (또는 새로운 함수정의 부분이 시작되는 곳에 있는 블록 주석에는 위쪽은 2개 아래는 1개의 라인이 좋다.).

라인 주석

라인 주석은 서술문과 같은 위치에 있는 주석이다. 라인 주석은 아껴서 사용해야만 한다.
라인 주석은 적어도 그 서술문으로부터 공백 2개로 분리해야 한다. 라인주석은 #와 공백한개로 시작해야만 한다.

라인 주석이 명백한 사실을 기술할때는 사실 산만스럽고 불필요하다. 이것을 사용하지 마라:

x = x+1                 # Increment x
그러나 때로, 이럴때는 유용하다 :
x = x+1                 # Compensate for border

문서화 문자열

모든 모듈은 보통 문서화 문자열을 가진다, 그리고 하나의 모듈이 수출한 모든 함수와 클래스 또한 문서화 문자열을 가진다. 공용 메쏘드 (__init__구성자를 포함하여) 또한 문서화 문자열을 가져야 한다.

한 스크립트(독자적 프로그램)에서 문서화 문자열은 "사용법" 메시지로 사용가능해야 한다. "사용법"은 스크립트가 부정확한 인수 혹은 인수를 빼먹고 (혹은 "-h"옵션을 "도움"을 위해 사용하여) 호출할 때 출력된다.
그런 문서화 문자열은 스크립트의 함수와 명령어 라인 구문, 환경 변수, 그리고 파일들에 대하여 문서화를 해 주어야만 한다. 사용법 메시지는 아주 우아하게 (몇개의 화면에) 치장할수도 있다 그리고 충분하게 새로운 사용자가 명령어를 적절히 사용할수 있도록 해 주어야만 할 뿐 아니라, 정밀한 사용자를 위해서 모든 옵션들과 인수들에 대한 완전한 참조를 제공하여야 한다.

일관성을 위하여, """ 세개의 이중인용부호"""를 문서화 문자열주위에 항상 사용하라.

두가지 형태의 문서화 문자열이 있다 : 한줄짜리 그리고 여러줄 문서화 문자열.

한줄짜리 문서화 문자열

한줄짜리 문서화 문자열은 진짜로 명백한 경우에 사용한다. 실제로 한줄에 딱 맞는다. 예를 들면:

def kos_root():    """Return the pathname of the KOS root directory."""    global _kos_root    if _kos_root: return _kos_root    ...

주의사항:

  • 삼중 부호는 문자열이 한 라인에 맞을 때 조차도 사용한다. 이렇게 하면 나중에 확장하기에 편하다.
  • 닫기 부호는 열기 부호와 같은 라인에 위치한다. 이렇게 해야 한줄짜리에는 더 좋아 보인다.
  • 문서화 문자열의 앞 혹은 뒤에는 공백라인이 없다.
  • 문서화 문자열은 구두점으로 끝나는 구절이다.
    그것은 함수의 효과를 명령어로 ("Do this", "Return that")지시하는 것이지, 설명으로 지시하지는 않는다. : 예. don't write "Returns the pathname ..."

여러-줄 문서화 문자열

여러줄 문서화 문자열은 한줄 문서화 문자열과 똑 같은 요약 라인들로 구성되는데, 공백열이 하나 따르고, 다음에 더 자세한 설명이 따른다. 요약 라인은 자동적으로 인덱스를 하는 도구들에 의하여 사용되어진다;
요약라인은 한줄에 꼭 맞아야 하고 나머지 문서화 문자열들과 하나의 공백라인에 의하여 나누어진다는 사실은 중요하다.

전체 문서화 문자열은 첫 번째 라인에 있는 부호와 같은 위치에 들여쓰기 된다.( 아래의 예를 보라).
문서화 문자열의 처리 도구는 그 문서화 문자열의 첫 번째 라인 이후로 나타나는 첫 번째 비공백라인의 위치와 똑 같은 들여쓰기 위치로 두 번째 이후 라인으로부터 많은 양의 들여쓰기를 제거할 것이다. 문서화 문자열에 있는 이후의 라인들의 상대적인 들여쓰기는 유지된다.

여러줄 문서화 문자열의 가장 마지막 문단과 닫기 부호 사이에는 공백라인 하나를 삽입하기를 추천한다, 그리고 닫기 부호는 하나의 라인에 단독으로 놓기를 추천한다. 이런 식으로 , Emacs의 문단채우기 명령어가 사용될 수 있다.

나는 또한 모든 문서화 문자열(한-줄 혹은 여러-줄)앞과 뒤에는 한개의 공백라인을 두기를 권장한다.
문서화 문자열은 클래스를 문서화 하고 -- 일반적으로 말해서, 클래스의 메쏘드는 한개의 공백라인으로 각각 분리되고, 문서화 문자열은 그 첫번째 메쏘드로부터 한개의 공백 라인만큼 떨어질 필요가 있다 ; 균형을 위해, 클래스의 머리부와 문서화 문자열 사이에 한 개의 공백라인을 가지는 것을 선호한다. 함수를 문서화 하는 문서화 문자열은 함수의 몸체가 다수의 공백 라인으로 분리되어 씌여지지 않는 한, 일반적으로 이러한 요구사항을 갖지는 않는다. -- 이러한 경우에는, 문서화 문자열을 다른 섹션으로 다루고, 그것을 하나의 공백라인으로 대체하라.

하나의 모듈을 위한 문서화 문자열은 일반적으로 클래스, 예외 그리고 함수들 (그리고 다른 어떠한 객체들)에 대한 목록을 기술해야만 하는데 그것들은 각각에 대하여 한-줄 요약을 가지고, 모듈에 의하여 수출된다. (이러한 요약들은 일반적으로 객체의 문서화 문자열에 있는 요약 라인보다는 덜 상세하다.)

함수나 메쏘드를 위한 문서화 문자열은 그것의 행위를 요약해야만 하고 그것의 인수들, 반환값, 부작용, 예외상황 발생, 그리고 호출되었을 때의 제한 상황들에 대하여 문서화를 (가능하다면 모두) 해야만 한다. 선택적 인수는 명료하게 보여져야만 한다. 키워드 인수가 인터페이스의 부분인지 아닌지가 문서화 되어야 한다.

클래스를 위한 문서화 문자열은 그것의 행위를 요약하고 공용메쏘드와 실체변수들의 목록을 나열해야 한다.
만약 클래스가 하부 클래스가 된다면, 그리고 하부클래스와의 부가적인 인터페이스를 가진다면, 이러한 인터페이스는 각각 (문서화 문자열의 형태로) 나열되어져야만 한다. 클래스 구성자는 자신의 __init__메쏘드를 위하여 문서화 문자열로 문서화 되어야 한다. 각각의 메쏘드들도 자신들만의 문서화 문자열로 문서화 되어야 한다.

하나의 클래스가 또다른 클래스를 하부클래스로 가지고 그것의 행위가 거의 그 클래스로부터 상속된다면, 그것의 문서화 문자열은 이것을 언급해야만 하고, 그 차이를 요약해야만 한다.
"override" 동사를 사용하여 하부클래스의 메쏘드가 상위클래스의 메쏘드를 대체하고 그리고 그것를 호출하지 않는다는 것을 지시하라; "extend"동사를 사용하여 하부클래스의 메쏘드가 상위클래스의 메쏘드를 호출한다는 것을 (덧붙이자면 자신의 행위에) 지시하라.

실행중인 텍스트에서 대문자로 함수나 메쏘드의 인수를 언급하는 Emacs의 관례를 사용하지마라
파이썬은 대소문자를 구별하며 그리고 인수의 이름은 키워드 인수로 사용될 수 있다, 그래서 문서화 문자열은 정확한 인수의 이름을 문서화하여야 한다. 하나의 인수는 두개의 대쉬를 이름과 설명을 구분짓는데 사용하여, 각각 한 라인에 나열하는 것이 좋다. 다음과 같이:

def complex(real=0.0, imag=0.0):    """Form a complex number.    Keyword arguments:    real -- the real part (default 0.0)    imag -- the imaginary part (default 0.0)    """    if imag == 0.0 and real == 0.0: return complex_zero    ...

버젼 기록유지하기

여러분이 소스파일에 RCS 또는 CVS 표지를 가져야만 한다면, 다음과 같이 하라.

__version__ = "$Revision: 1.4 $"# $Source: /home/guido/ftp/pub/www.python.org/doc/essays/RCS/styleguide.html,v $

이 라인들은 모듈의 문서화 문자열 뒤에 포함되어져야만 하며, 다른 코드의 앞에는, 위 아래로 하나의 공백라인으로 구분해서 포함되어져야 한다.

이름짓기 관례

파이썬 라이브러리의 이름짓기 관례는 약간은 혼란스럽다, 그래서 우리는 이것을 완벽하게 일관성이 있도록 하지는 못할 것이다.-- 그럼에도 불구하고, 여기에 약간의 가이드라인이 있다.

설명적인: 이름짓기 스타일

많은 수의 서로 다른 이름짓기의 스타일이 있다. 그것들이 무엇에 사용되는지로부터 각각, 어떤 이름 짓기 스타일이 사용되었는지를 알아낼수 있도록 도와 준다. 다음의 이름짓기 스타일은 일반적으로 자주 보는 것이다:

  • x (한개의 소문자)
  • X (한개의 대문자)
  • lowercase (소문자)
  • lower_case_with_underscores (밑줄로 연결된 소문자)
  • UPPERCASE (대문자)
  • UPPER_CASE_WITH_UNDERSCORES (밑줄로 연결된 대문자)
  • CapitalizedWords (또는 CapWords) (단어의 첫자만 대문자)
  • mixedCase (첫번째 문자가 소문자이므로 CapitalizedWords 와는 다르다!)
  • Capitalized_Words_With_Underscores (보기 흉하다!)

또한 짧고 유일한 접두사를 사용하여 관계된 이름들을 무리짓는 스타일도 있다. 이것은 파이썬에서 많이 사용되지는 않지만, 완벽을 위해 언급한다. 예를 들어, os.stat() 함수는 하나의 터플을 돌려주는데 그 터플의 각 항목은 전통적으로 st_mode, st_size, st_mtime 등등과 같은 이름을 가진다. X11 라이브러리는 모든 공용 함수에 대하여 이끄는 X를 사용한다. (파이썬에서, 이러한 스타일은 일반적으로 불필요하게 생각된다. 속성과 메쏘드의 이름은 객체의 이름으로 접두어가 붙고, 그리고 함수의 이름은 모듈의 이름으로 접두어가 붙기 때문이다.)

게다가, 다음의 이끄는 혹은 끌리는 밑줄문자를 사용하는, 특별한 형태가 보인다. (이것들은 일반적으로 어떠한 경우의 관례와도 결합될 수 있다.):

  • _single_leading_underscore: 약한 "내부 사용" 지시자 >
    ;(예. "from M import *" 은 밑줄문자로 시작하는 객체들을 수입하지 않는다).
  • single_trailing_underscore_: 파이썬의 키워드와의 충돌을 피하기 위하여 관례적으로 사용됨
    예를 들어 : Tkinter.Toplevel(master, class_="ClassName").
  • __double_leading_underscore: 파이썬 1.4에서의 클래스-사적인 이름들.
  • __double_leading_and_trailing_underscore__: 사용자-제어 이름영역에 존재하는 "매력적인" 객체 혹은 속성 예를들어 : __init__, __import__ or __file__.
    때때로 이것들은 사용자에 의해서 어떠한 매력적인 행위를 촉발하도록 정의된다. (예 : operator overloading);
    때때로 이것들은 하부구조에 의해서 삽입되어져 디버깅 목적 혹은 자신만의 사용을 위해 쓰여진다. 하부구조(느슨하게 정의 하여 파이썬 인터프리터와 표준 라이브러리)는 미래의 버젼에 매력적인 속성들의 목록을 추가하기로 결정할 수 있다.
    사용자 코드는 일반적으로 자기 자신만 사용하기 위하여 이런 관례를 사용하는 것을 자제해야 한다. 하부구조의 부분이 되기를 열망하는 사용자 코드라면 밑줄들 안에서 이것을 짧은 접두사와 결합할 수 있다.
    예를 들어 : __bobo_magic_attr__.

지시적인: 이름짓기 관례

모듈 이름

모듈 이름은 MixedCase 이거나 lowercase 일 수 있다. 어떤 것을 사용할지 결정하는 명료한 관례는 없다. 한개의 클래스(혹은 많은 수의 밀접하게 연관된 클래스들, 또 약간의 부가적인 지원까지)를 수출하는 모듈은 가끔 MixedCase의 형태로 이름지어지며, 모듈의 이름으로 클래스의 이름도 동일하게 짓는다(예 : 표준 StringIO 모듈). 한 무리의 함수를 수출하는 모듈은 보통 모두 lowercase의 형태로 이름지어진다.

모듈의 이름은 화일의 이름에 사상이 되고, 어떤 화일 시스템은 대소문자를 구별하고, 긴 화일 이름을 잘라버리므로, 모듈의 이름이 아주 간결하게 선택되어야 하며 단지 다른 모듈이름과 대소문자만 달라서 충돌하지 말아야 한다. -- 이것은 유닉스에서는 문제가 되지 않는다, 그러나 코드가 맥이나 윈도우로 이식되면 문제가 발생할 것이다.

새로이 떠오르는 관례가 하나 있다. C 나 C++로 씌여진 확장모듈이 더 고수준의 (예를 들어 더욱 객체 지향적인) 인터페이스를 제공하는 파이썬 모듈을 동반할 때, 파이썬의 모듈 이름은 CapWords의 형태를 가지는 반면에, C/C++ 모듈은 모두 소문자로 이름짓고 하나의 이끄는 밑줄 문자를 가진다 (예를 들어 Tkinter/_tkinter).

"패키지"들은 ("ni"모듈이 지원하는, 모듈의 집합) 일반적으로 모두 소문자의 짧은 이름을 가진다.

클래스 이름

거의 예외없이, 클래스 이름은 CapWords 관례를 사용한다. 내부적인 사용을 위한 클래스는 부가적으로 이끄는 밑줄문자 하나를 사용한다.

예외 이름

하나의 모듈이 모든 종류의 조건들을 처리하기 위하여 하나의 예외(처리)를 정의한다면, 일반적으로 그것을 "error"혹은 "Error"라고 부른다. 내가 아는 한, 내장(확장) 모듈은 "error"(예를 들어 os.error)를 사용하는 반면에, 파이썬 모듈은 일반적으로 "Error"(예를 들어 xdrlib.Error)를 사용한다.

함수 이름

하나의 모듈에 의하여 수출된 단순한 함수는 CapWords 스타일을 사용하거나 lowercase (또는lower_case_with_underscores) 형태를 사용할 수 있다.

나는 특별히 선호하는 바는 없지만, 중요한 기능(예를 들어 nstools.WorldOpen())을 제공하는 함수에는 CapWords 스타일을 사용하고, 반면에 lowercase의 스타일은 "유틸리티"함수(예를 들어 pathhack.kos_root())에 더욱 많이 사용한다고 믿고 있다.

전역 변수 이름

(이런 변수들이 하나의 모듈안에서만 사용될것이라고 가정해보자.) 관례는 수출된 함수의 관례와 거의 동일하다. "from M import *"의 형식을 통하여 사용되도록 디자인된 모듈은 하나의 밑줄문자로 자신의 전역 변수 (그리고 내부 함수와 클래스)들에 접두사를 붙여서 그들을 수출하는 것을 막아야 한다.

메쏘드 이름

음, 이야기는 함수와 거의 동일하다. ILU를 사용할 때, 여기에 좋은 관례 하나가 있다 :

ILU 인터페이스를 통하여 발표된 메쏘드에는 CapWords를 사용하라. 객체형의 구현의 일부인, 다른 클래스 혹은 함수가 접근하는 메쏘드에는 소문자를 사용하라.
하부 클래스 혹은 상위 클래스의 속성들이 전혀 충돌하지 않거나 또는 하부 클래스 하나가 실제로 접근할 필요가 있을 때 "내부" 메쏘드와 실체 변수들에는 앞에 하나의 밑줄문자를 사용하라.

오직 현재의 클래스만이 하나의 속성에 접근하는 것이 중요할 경우에는 (클래스-지역 이름, 파이썬 1.4에서는 강제적임) 앞에 두개의 밑줄문자를 사용하라. (그러나 파이썬은 충분히 많은 루프구멍이 있어서 끈질긴 사용자는 그럼에도 불구하고 예를들어, __dict__ 속성을 통하여 접근할 수 있다. 오직 ILU 혹은 파이썬의 제한된 모드만이 XXX를 할것이다.


번역기간 : 2001.07.11 - 2001.07.15
현재버전 : 수 정 요 망
번 역 자 : 전순재

한글로 일단 바꾸고 생각해 본다.
내용은 본인도 잘 모름. 혹시 오역이 있으면 게시판에 알려주시면....고치겠습니다.

 

출처 : http://home.hanmir.com/~johnsonj/etc/Python%20Style%20Guide.htm

MonthDayCnt는 calendar 모듈에 이미 들어있습니다.

>>> import calendar
>>> MonthDayCnt3 = lambda year, month: calendar.monthrange(year, month)[1]
>>> MonthDayCnt3(2000, 2)
29
>>> print calendar.month(2000, 2)
February 2000
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29
>>>

 

출처 : http://bbs.python.or.kr/viewtopic.php?t=14603

 

'programming > python' 카테고리의 다른 글

파이썬 스타일 지도서  (0) 2004.01.27
[Sample] 베타뉴스 겔러리 그림 긁어 모으기  (0) 2004.01.27
파이썬 2.3 간편 참조서  (2) 2004.01.25

 

import urllib
import re
import string

print "="*50
print " Beta News EntGirm Download Script!"
print "="*50
num_start = 0 #시작할 그림 번호
num_end = 2666 #마지막 그림 번호
WORK_DIR = "c:\\dir\\beta" #저장할 디렉토리 c:\dir 에 저장됩니다. 그리고 파일 앞에 beta라는 이름이 붙습니다.

def saveJPG(num, jpg_name): #파일 이름을 받아서 파일을 저장하는 함수
pagename = "http://data.betanews.net/imgdb/screen_star/%s.jpg" % jpg_name #실제파일이 있는 디렉토리
print pagename
filename = WORK_DIR + jpg_name+'.jpg' #파일이름을 만들어줌
print num, filename #번호와 파일 이름을 출력해 줍니다.
aa = urllib.urlopen(pagename) #jpg에대한 정보를 가지고있는 객체를 만들어 줍니다.
try:
f1 = open(filename, "wb") #파일을 바이너리 모드로 저장함니다.
f1.write(aa.read()) #실제 주소에서 jpg파일을 읽고 씀니다.
f1.close
except:
print "error on open %s" % filename #에러가 나면 에러 출력


for num in range(num_start,num_end):
page = "http://betanews.net/screenshot/read.html?table=screen_star&page=1&num=%d&no=5022&depth=0" % num #베타뉴스는 num숫자만 바꾸어 주면 됩니다.
try: #가끔식 에러가 나서 ...
a = urllib.urlopen(page) #페이지 정보를 읽어옴..
except:
print "Time Out...."
continue
data = a.readlines()
p = re.compile('.*image=.*') #정규표현식으로 imgage가 있는 곳만 보여줍니다.
for line_one in data:
m = p.match(line_one)
if m:
tmp = string.find(line_one,'image=') #처음 발견된 곳을 정수형 값으로 돌려줍니다.
tmp_line=line_one[tmp+6:tmp+16] #파일 이름만 함수로 넘겨주기 위함 확장자 없이
saveJPG(num, tmp_line)

print "Good Day!" #모든 파일을 읽어오면 ....


출처 : http://bbs.python.or.kr/viewtopic.php?t=14659

'programming > python' 카테고리의 다른 글

파이썬 스타일 지도서  (0) 2004.01.27
특정 달의 날짜 수 구하기  (4) 2004.01.27
파이썬 2.3 간편 참조서  (2) 2004.01.25

파이썬 2.3 간편 참조서입니다.

 

내용이 좀 길어서 포스트 형태 유지를 위해 파일을 첨부합니다.

웹으로 바로 보실 분은 http://home.hanmir.com/~johnsonj/etc/한글판PQR232EUCKRPRINT.html 입니다.

출처는 http://home.hanmir.com/~johnsonj/ 입니다.

좋은 문서들 많이 있습니다.

 

 

'programming > python' 카테고리의 다른 글

파이썬 스타일 지도서  (0) 2004.01.27
특정 달의 날짜 수 구하기  (4) 2004.01.27
[Sample] 베타뉴스 겔러리 그림 긁어 모으기  (0) 2004.01.27

+ Recent posts