default value parameter 가 가독성에 미치는 해악

default value parameter 는 함수에 파라미터를 지정할 때 자주 쓰이는 방법이다. def foo(a: bool = True): if a: return "foo" else: return "bar" 문제는 이 방법이 함수의 제작자의 경우에는 명시적으로 느껴지지만 사용자 혹은 독자의 경우에는 굉장히 묵시적이라는데 있다. # default argument >> foo() "foo" # positional argument >> foo(True) "foo" # keyword argument >> foo(a=False) "bar" default value parameter 는 positional / keyword argument 외에도 하나의 방법을 더 늘려주는데, 명시적으로 argument 를 넘기지 않아도 이미 지정된 default value 를 함수 내에서 사용할 수 있게 끔 한다....

December 18, 2023 · 2 min · Dongwook Kim

Mixin class 사용시 app 간 계층 구조

앞서 포스팅한 circular import 에 대한 생각 에서 해당 문제가 발생한 경우, 계층 구조를 먼저 생각해보자는 이야기를 했었다. 이번에는 이어서 class 의 공통된 기능을 뽑아낼 때 계층 구조를 잘 잡기 위한 방법을 생각해보았다. 일반적으로 Mixin class 는 하위 클래스들의 공통을 묶어 상위 abstract 로 뽑는데 사용되나, 가끔은 상위 클래스들에 공통된 기능을 붙이는 용도로도 사용된다. django 로 가정하고 예시를 든다. # A app class A(models.Model): nickname = models.CharField(...) def validate_nickname(self): ... # B app class B(models....

December 18, 2023 · 3 min · Dongwook Kim

Python 내부의 C 코드 들여다보기

! 아래의 예제는 모두 macOS Monterey 12.5.1 에서 작성되었다. 먼저 python 내부에 c 코드를 들여다보기 위해서는 cpython 소스를 받아야 한다. git clone https://github.com/python/cpython cd cpython 원하는 버전으로 branch 를 바꿔주고 컴파일을 진행한다. configure 옵션 참고 git switch 3.9 ./configure --with-pydebug --with-openssl=$(brew --prefix openssl) make -s -j2 make 시 macOS 에서 'lzma.h' file not found 가 발생할 경우 brew 로 xz 를 설치하고 환경변수를 잡아준다. 환경마다 path가 다를수 있음에 주의...

October 21, 2022 · 4 min · Dongwook Kim

PEP 3119 ABC 번역

PEP 3119 – Introducing Abstract Base Classes original link 이론적 해석 객체 지향 프로그래밍에서, 객체와 상호작용하는 사용 패턴은 두가지 기본 분류로 나눌 수 있다. 하나는 ‘호출(invocation)’ 이고 다른 하나는 ‘분석(inspection)’ 이다. 호출은 객체의 메소드를 호출하는 것을 의미한다. 대개 다형성과 결합되어 메소드를 호출하면 어떤 타입의 객체이냐에 따라 다른 코드를 실행하게 된다. class A: def foo(self): print("A") class B(A): def foo(self): print("B") A().foo() B().foo() 분석은 외부 코드(해당 객체의 메소드 밖의)에서 해당 객체의 타입이나 프로퍼티를 확인하고 확인한 정보에 따라 어떻게 객체를 다룰지 결정하는 것을 의미한다....

September 23, 2022 · 3 min · Dongwook Kim

Circular import에 대한 생각

인터넷을 보면 많은 circular import 문제 해결 방법을 찾을 수 있다. 대표적인 해결방법. def foo(): import smth ... 위와 같이 함수 내부에서 import 를 한다면 회피가 가능하다. 프로그램은 문제 없이 동작하기 시작하고, 이후 이 문제는 그대로 잊혀진다. 이게 옳은 방법일까? 일단 해당 문제가 왜 발생하는 지부터 생각해보자. # foo.py import bar ... # bar.py import foo ... 이렇게 서로를 import 하는 경우 발생한다. 개발을 하다보면 흔하게 발생하는 경우인데, 단순히 위에 소개한 방법으로 회피하는 것만 고려하여 아쉬움이 있다....

February 21, 2021 · 2 min · Dongwook Kim

Early return에 대한 생각

early return 이란 특정 상황에서 function 내 주요 로직이 실행되기 이전에 return을 함으로써 실행 cost를 줄이고 가독성을 높이는 방법이다. def notify(data): if not data.get("to"): return False if data.get("platform") not in NOTIFY_PLATFORMS: return False return NOTIFY_PLATFORMS[data["platform"]](data) 위의 경우에서 보듯이 알림을 주는 function에서 전처리를 통해 실제 로직이 실행 되기 이전에 return을 주는 것을 알 수 있다. 안좋은 예로 보면 def notify(data): if not data.get("to"): return False elif data.get("platform") not in NOTIFY_PLATFORMS: return False else: return NOTIFY_PLATFORMS[data["platform"]](data) 와 같이 if-elif-else 로 모든 로직을 감싸는 경우라고 생각 되는데, 이 경우는 해당 function의 정상 로직이 어느 분기인지 알기 힘들다....

February 17, 2021 · 2 min · Dongwook Kim