파이썬 강좌 – 코드를 작성하는 사람의 의도

  1. 프롤로그
  2. 개발 첫걸음
    1. 컴퓨터 구성요소 - 컴퓨터는 어떤 걸 할 수 있나?
    2. 개발과 관련된 용어
    3. 파이썬의 선택 - 왜 파이썬인가?
    4. 파이썬 설치 - Hello World 출력하기
    5. Visual Studio Code 의 편리한 기능
    6. REPL과 콘솔 창 - 파이썬 동작시키기
  3. 파이썬 기초
    1. 기초 입출력 - 소통하기
    2. 변수와 대입 - 기억하기
    3. 연산자 - 계산하기
    4. 조건문 - 분기를 만들기
    5. 반복문 - 비슷한 작업을 반복하기
    6. 변수와 리스트 - 비슷한 변수들을 묶기
    7. for, range - 리스트의 항목을 다루기
    8. 파이선 기초 꿀팁
      1. 함수와 메소드의 호출 - 편리한 기능 이용하기
      2. 모듈 설치와 사용 - 유용한 기능 끌어다 쓰기
      3. 문자열 - 텍스트 다루기
  4. 파이썬 중급
    1. 정규표현식 - 문자열을 검색하고 치환하기(작성중)
    2. 함수를 직접 만들기 - 자주 쓰는 기능을 묶기
    3. 딕셔너리, 튜플, 세트 - 변수를 다양한 방법으로 묶기
    4. 클래스와 객체 - 변수를 사람으로 진화시키기
    5. 상속 - 클래스를 확장하기
    6. 파이썬 중급 꿀팁
      1. 코드를 작성하는 사람의 의도(작성중)
      2. 정체성과 동질성 - 객체의 성질(작성중)
      3. 명령문, 표현식 - 문법을 이루는 것들 (작성중)
      4. 슬라이싱 - 리스트를 갖고 놀기
  5. 파이썬 고급
    1. 예외와 에러 - 예상치 못한 상황에 대응하기
    2. 특별 메소드와 연산자 - 파이썬의 내부 작동방식 이해하기
    3. 다양한 함수 인수 - 유연한 함수 만들기
    4. 시퀀스와 반복자 - 반복과 순회를 자유자재로 다루기
    5. 변수의 범위 - 이름 검색의 범위
  6. 파이썬 심화
    1. 제너레이터와 코루틴 -
    2. async와 await
    3. 데코레이터 - 함수의 기능을 강화하기
    4. 객체로서의 클래스 - 클래스를 동적으로 정의하기
  7. 파이썬 프로젝트 실습
    1. 원카드 게임 만들기 (1)
    2. 원카드 게임 만들기 (2)
  8. 실전 (파이썬 외적인 것들)
    1. 유니코드 - 컴퓨터에서 문자를 표기하는 방법
    2. html, css, 인터넷 - 자동화 첫 걸음 내딛기
    3. 네트워크 - 인터넷으로 통신하는 방법
    4. 문서 - 문맥을 읽어보기

의도가 담긴 코드

프로그래머라는 직업의 역사로 따지면 다른 직업보다야 그렇게 거창하지는 않습니다. 하지만 최신 기술과, 더 나은 세상으로 나아가는 새로운 방법론과, 논리적인 놀잇감으로서 프로그래밍은 폭발적으로 발전해왔고 그와 동시에 개발자들 사이에서도 일정한 문화가 생겨났습니다. 특히 코딩 방법론은 논쟁의 주잿거리로서 아주 인기가 많지요. 사람마다 코딩 스타일이 다른 건 누구나 인정하겠지만, 그러한 자유로움 속에서 어느 정도 약속된 스타일의 필요성 또한 인정되었습니다. 개발자들 간의 의사소통을 더 원활하게 해준다는 점에서 효율성과 직결되기 때문입니다.

개발자 유머. 코드 까먹음 이 코드를 작성했을 때에는 오직 신과 나만이 그 의도를 알았다. 이제는 신만 아신다.

어떤 코드가 어떻게 작동하는지는 코드를 읽을 수 있는 자라면 누구나 알 수 있습니다. 다만 시간이 걸릴 뿐이겠죠. 문제는 그 코드를 수정하거나 개선하게 되었을 때 입니다. 그 때에는 단순히 코드가 어떻게 동작하는지만 알면 안 됩니다. 하나를 수정하게 되면 주위의 모든 것들에게 영향을 줍니다. 그러므로 이 코드의 최종 역할이 무엇인지, 무엇을 건드리고 무엇을 건드리면 안 되는지, 그리고 추후 이 코드를 또 다시 수정할 누군가에게 이러한 일관성을 어떻게 전달할 것인지에 대해 고민해야 합니다.

그래서 소스 코드에 코드를 작성하는 사람의 의도를 담아야 합니다. 코드의 기능 뿐만이 아니라 코드의 목적이나 개선 방향까지 담아야 합니다. 그래서 문제를 잘게 쪼개어 캡슐화하고, 변수와 속성과 메소드와 클래스에 유의미한 이름을 짓고, 실수할 여지를 줄이기 위한 장치를 만들며, 설명이 필요하면 주석을 자세하게 답니다. 이러한 것 하나하나에 코드를 작성하는 사람의 의도가 담깁니다.

이러한 의도를 담는 방법은 코딩 방법론에 포함되어서 열렬히 논의되었습니다. 일정한 약속이 생겨났습니다. 프로그래밍 언어를 처음 접하느라 이러저러한 약속이 생소하다면 미리 언어 차원에서 친절하게 가이드라인을 제시해줍니다. 특히 파이썬 같은 경우에는 언어의 설계 철학과 코딩 스타일에 대해서 심사숙고한 언어입니다. 그래서 상대적으로 다른 언어에 비해 일관성을 쉽게 유지할 수 있고 쉽게 배울 수 있는 것입니다.


문법의 의미 (추가 예정)

  • while(True): 일단 무한 반복하고, 내부에서 break를 통해 루프를 멈출 것이라는 걸 기대할 수 있습니다.

인수의 기본값을 None으로 지정하기

파이썬에서는 함수를 정의할 때 def test(a, b=None) 과 같은 형태를 자주 접할 수 있습니다. 여기서 b의 기본값은 None인데요, 이렇게 지정해두는 것은 b가 불변형 객체(int, float, str, tuple 등)이 아니라 가변형 객체(list, 일반 객체 등)를 받고자 하며, 사용자가 이 함수를 호출할 때 b의 존재 여부에 따라 함수의 작동을 달리 하겠다는 로직을 이 함수 내부에 만들겠다는 뜻입니다.

만약 b에 가변형 객체를 기본값으로 지정하게 된다면, b의 기본값은 모두 동일한 객체를 가리키게 됩니다. 이게 무슨 말이냐 하는 건, 기본값으로 빈 리스트와 같은 객체를 사용하는 건 절대 좋은 아이디어가 아니라는 뜻입니다. 다른 객체도 마찬가지입니다. 함수의 기본값은 호출할 때마다 새롭게 생겨나는 것이 아니라, 함수를 정의할 때 그 내용에 포함되어서, 해당 기본값은 오직 1회 평가됩니다.

다음 코드를 예를 들어봅시다. 리스트에 내용을 추가하여 다시 반환하는 간단한 함수입니다. 만약 sequence가 인수로 주어지지 않는다면, 빈 리스트를 만들어서 거기에 some을 넣어 반환하고 싶습니다. 그래서 아래와 같은 코드를 만들었습니다

def addSomething(some, sequence=[]):
    sequence.append(some)
    return sequence

something = ['하', '이', '요']
something = addSomething('맨~', something)
print(something)

some1 = addSomething('ab')
print(some1)

some2 = addSomething('cd')
print(some2)

print('some1과 some2가 동일한가요? >>', id(some1) == id(some2))
기본값으로 빈 리스트 지정했을 때의 결과 기본값으로 빈 리스트 지정했을 때의 결과

결과를 시각화하였습니다. addSomething의 기본값, some1, some2가 모두 같은 객체를 가리키고 있습니다. 이는 우리가 의도한 바가 아니지요. 이 코드를 옳게 바꾼다면 다음과 같습니다.

def addSomething(some, sequence=None):
    if sequence is None:
        sequence = []
    sequence.append(some)
    return sequence

something = ['하', '이', '요']
something = addSomething('맨~', something)
print(something)

some1 = addSomething('ab')
print(some1)

some2 = addSomething('cd')
print(some2)

print('some1과 some2가 동일한가요? >>', id(some1) == id(some2))
기본값으로 None 했을 때의 결과 기본값으로 None 했을 때의 결과

이름 짓기

  • 변수명은 소문자로 시작합니다.
  • 클래스명은 대문자로 시작합니다.
  • 클래스 정의 내에서, 속성과 메서드는 소문자로 시작합니다.
  • 어떤 값이 영원히 바뀌지 않기를 원한다면 그 이름을 전부 대문자로 작성합니다. 단어를 나눌 때에는 언더바(_)를 사용합니다. 예를 들어 고정된 세금 비율을 나타내는 상수는 TAX_RATES와 같이 작성합니다. 파이썬에서는 상수를 지원하지 않으므로 이름을 대문자로 했다고 해서 수정이 불가능한 것은 아니지만, 다른 사람들에게 "이 값은 영영 바꾸지 않았으면 좋겠어."라고 알릴 수 있습니다.
  • get으로 시작하는 메서드는 무언가를 반환함을 기대할 수 있으며, set으로 시작하는 메서드는 이를 통해 어떤 것을 수정(modify)할 수 있음을 암시합니다.
  • 어떤 이름을 외부로 공개하고 싶지 않을 경우 언더바(_)로 시작하는 변수명 혹은 클래스명을 사용합니다. 언더바를 쓰더라도 접근은 가능하나 다른 사람들에게 이 이름을 비공개로 하고 싶다는 것을 알릴 수 있습니다.
  • 파이썬에서는 앞뒤로 언더바 두 개(예: __init__)로 이루어진 메소드는 특별 메소드(special method)입니다. 특별 메소드는 파이썬 인터프리터가 호출하도록 설계되었으며, __init__을 제외하고 직접 호출하는 일은 거의 없도록 합니다.

어노테이션

어노테이션(추가 예정)은 함수의 파라미터나 리턴 값의 타입, 혹은 변수의 타입을 나타내는 주석입니다. 실제 프로그램 실행에는 아무런 영향을 미치지 못하지만, 에디터 등에서 타입을 추론해줄 수 있게 해주어, 자동 완성 기능 등의 더욱 편리하게 코딩할 수 있는 기반을 마련해줍니다.


주석

주석은 소스 코드의 어디에서나 적을 수 있는 부가 설명입니다. 코드를 작성하는 사람의 의도를 코드로써 충분히 풀어내지 못할 때에는 아주 종종 주석을 활용하게 됩니다. 대부분의 상황에서는 부족한 설명으로 의도를 완전히 파악하지 못할 바에야, 과한 설명으로라도 확실하게 이해시키는 것이 낫습니다. 대부분의 에디터에서는 주석이 색깔로 쉽게 구분되므로 가독성도 그렇게 크게 해치지 않습니다.


각종 에러와 값 (추가 예정)

예외에 대한 자세한 설명은 공식 문서에서 살펴볼 수 있습니다.

NotImplementedError

클래스를 설계할 때 하위 클래스에서 반드시 오버라이드하여 상세하게 구현해야 하는 메소드를 명시하고자 할 때 상위 클래스에서는 그 메소드의 내용으로 raise NotImplementedError(메시지)만 넣어놓게 됩니다.

NotImplemented

어떤 클래스의 연산자, 특히 수치형에서 작동하는 중위 연산자에서 지원하지 않는 연산이라는 것을 나타내기 위해 NotImplemented 값을 return 합니다. NotImplemented는 키워드이자 값입니다. 굳이 에러를 내지 않고 이런 요상한 값을 반환하는 이유는 파이썬 인터프리터가 다른 가능한 연산을 찾아볼 기회를 주기 위해서입니다. 예를 들어 어떤 클래스에서 __add__ 메소드를 구현했는데 이 메소드 내부에서 에러가 발생한다면, 파이썬 인터프리터는 다른 클래스의 __radd__ 메소드를 검색할 새도 없이 에러를 내뿜으며 종료됩니다. 하지만 NotImplemented를 반환한다면, 파이썬은 __radd__ 메소드를 검색해보는 시도 또한 해봅니다. 모든 시도가 NotImplemented로 끝난다면, 그제서야 파이썬은 TypeError를 발생시킵니다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

Scroll to top