Python tech/고급 파이썬 공부

파이썬다운 코드란? (파이써닉하게 코딩하기)

콜레오네 2023. 3. 8. 23:06

수많은 프로그래밍 언어는 저마다 장단점이 있다.

파이썬은 가독성이 쉽고 뭐 내장모듈이 많고 어쩌고... 이렇게들 많이 말하곤 한다.

각 프로그래밍 언어의 강점을 잘 살리고, 약점을 커버할 수 있도록 설계하는 것이 바람직하다고 생각한다.

그렇다면, 파이썬답게(파이써닉하게) 코드를 작성하는 방법은 무엇일까?
.

해당 포스팅은 [클린코드, 이제는 파이썬이다] 저서의 일부입니다.


파이썬의 선 (Zen of Python)

파이썬 언어 설계와 프로그램을 위한 20가지 지침이라고 한다.
아래처럼 import this 를 불러오면 볼 수 있다.
이중 몇 가지 재미난 부분에 대해 알아보자

아름다운 것이 흉한거보다 낫다

당연한 사실이다. 파이썬은 중괄호가 사라지고 간결하게 코드를 작성하게 거의 강제하면서, 가독성을 높이고 보기 깔끔하게 하였다.
프로그래밍에서 가독성은 협업에 있어 매우 중요한 부분이다.

명시적이어라. not 암시적

누가봐도 하나의 뜻으로 해석될 수 있게, 본인만의 언어도 중의적인 뜻도 아닌, 명시적으로 코드를 작성하자

펼쳐놓은 수평 구조가 좋다. not 중첩된 계층 구조

이를 테면

# 보기만해도 끔찍하다
hello.world.welcome.name()
pythonic[2]['language'][select]

한 줄 코드가 잘하는 거라고 생각하지 말자

= 드문드문한 것이 조밀한 것보다 좋다
한줄코딩이 마치 실력있는 사람인 것처럼 보이는 경우가 많다.
잔 스킬이 좋을 뿐이지, 절대 좋은 코드는 아니다. 남이 알아보기에 최악이다.

에러를 마주한다면, 대충 넘기지 말아라

에러를 무시하거나 가볍게 넘기기보다, 명확하게 인지하고 해결하려고 해야한다.
그리고 에러는 이것저것 시도해보다가 어중간하게 해결되어선 안된다.
에러가 해결되어야하는 이유를 명확히 파악하고, 정확히 해결해주어야 한다.

네임스페이스는 매우 훌륭하다

내장함수에서 사용되는 네이밍을 쓰는 것은 (open(), read() 등)
어떤 기능을 하는 함수인지를 알 수 있기에 매우 좋은 아이디어이다.
클래스를 만들더라도, what.close() 라고 한다면, 누가봐도 해당 객체를 닫아줄것 같으니까

파이썬에서 국룰로 통하는 그런 것들

range() 대신 enumerate()

iterable 객체를 인자 하나씩 전달해주는 것은 파이썬 종특이다.
그러니 잘 이용해야하는데, 여전히 range(len(list))를 사용하여 인덱싱을 하려고 한다.
그러지말고 enumerate()를 사용하자

# tuple로 첫번째는 index, 두번째는 인자를 전달해준다.
## 굳이 range를 사용할 필요가 없다.
for index, obj in enumerate(iterObj):
    print(index, obj)

# 인덱싱이 필요없다면, 이렇게 쓰는 것도 방법이다.
## 중요한 것은 enumerate() 짱짱
for _, obj in enumerate(list):
    pass

open(), close() 보단 with()

open()으로 객체를 열어주고, close()로 닫아주는 것 얼마나 귀찮은가
사실 요즈으음에는 전부 with로 대체되긴 했지만, 한 줄로 처리되고 자동으로 close되니 얼마나 편리한가

# Bad
f = file.open()
# do something
f.close()

# Good
with open(file) as f:
    pass

백슬레시가 많다면? 원시 문자열!

원시 문자열 : r 접두사가 붙은 문자열 리터럴
파이썬에서는 일부 특수문자를 표현하기위해 백슬레시를 붙여줘야한다.
너무 백슬레시가 많다면 귀찮으니, 원시 문자열로 통일하자.
필자도 원시 문자열이 예전 코드, 혹은 허접한 코드로 보일 시절이 있었으나, 원시 문자열이 더 바람직하답니다.

# Bad
path = "C:\\this\\newdir\\hello\\"

# Good
path = r"C:\this\newdir\hello\"

문자열 포매팅 갑은 f-string

파이썬에서 문자열을 표현하는 방법은 다양하며, 지속 진화해왔다.

apple = 5
banana = 7

# 예전 방법 1
string = 'apple is ' + str(apple) + ", banana is " + str(banana)

# 예전 방법 2
string = "apple is %d, banana is %d" % (apple, banana)

# 예전 방법 3
string = "apple is {}, banana is {}".format(apple, banana)

# 그리고 f-string
string = f"apple is {apple}, banana is {banana}"

과연 뭐가 제일 좋은 방법인진 누가 봐도 알것 같다.

체이닝을 활용하자

체이닝, 말 그대로 체인처럼 연결되어있는 구조
바로 예시를 보자

# Bad
a = 1
b = 1
c = 1

# Good
a = b = c = 1

## 조건식에서도 허용된다
# Bad
if a < b and b < c:
    pass

# Good
if a < b < c:
    pass

채이닝을 활용하면 훨씬 간단하고 파이써닉하다

변수값 존재 여부 확인에는 iter 자료형을 써보자

# Bad
if fruit == "apple" or fruit == "banana" or fruit == "melon":
    pass

# Good
if fruit in ('apple', 'banana', 'melon'):
    pass

자, 이제 좀더 파이써닉해져보자

반응형