이 전글 '판교사투리' 에서 의사소통의 중요성을 느낀사람들은
'클린코드' (Clean Code) 와 '코드 컨벤션' (Code Convention) 에 대해 조금은 생각해보았을 것이다.
두 말이 비슷해보이고 혼동하기 쉬운데
코드 컨벤션 (Code Convention)
가독성과 유지보수에서 이점을 가진 '클린코드'(Clean Code) 를 작성하기 위한 일종의 규약(하나의 작성 표준)
이라고 생각하면 될것이다.
흔히 개발자의 skill set 중에 가장 중요한 요소가 'communication' 이라고 이야기 하는데,
일반적인 직군에서의 'communication' 은 기본적인 의사소통 을 지칭하거나
더 나아가 일종의 '업무 센스' 를 뜻하기도 한다
그러나 개발자의 'communication' 은 앞서 언급한 기본적인 의사소통과 업무 센스에 더불어
'클린코드'(Clean Code) 와 '코드 컨벤션' (Code Convention) 을 갖추어야 한다고 합니다.
사용하는 언어마다, 개발중인 프로젝트마다, 업무지시를 내린 회사마다 약간의 차이는 있겠지만 신입 개발자라면 입사후, 회사 내에 작성된 코드 컨벤션이 어떻게 되는지 파악하는 것이 기본 소양이지 않을까 생각한다.
그래서 코드컨벤션이 도대체 뭔데?? 예시 없어?? 라고 말한다면
완벽한 코드 컨벤션은 없습니다.
효율성이나 편의성이 확실히 증명되어서 채택된 방식이 있을 수도 있지만 대개 취향의 차이인 경우가 많으며,
각 언어별 코딩을 잘하는 실력자(괴물)분들이 취향의 차이라서 그런지 서로 많이들 싸우기도 합니다.
대표적인 예시로는
1. 인덴트 2칸 vs 4칸 vs 8칸(...소수)
2. 인덴트 Tab vs Space
3. 괄호를 어떻게 열고 닫을 것이냐
4. 변수나 함수 등 이름짓는 법
5. 주석 다는 법
6. camelCase vs PascalCase vs snake_case vs hgCase vs ....
7. .....
이런것들이 있는데 벌써부터 정신이 아프기 시작합니다.
그렇다면 어떤 규칙을 따라야 하는데?? 라고하면
1. 창시자가 시키는대로 하기
2. 괴물 구글의 권장사항을 참조
3. 기타 괴물들의 의견을 참조
4. 커뮤니티와 통계를 참조
이 방법이 가장 효과적이지 않을까 생각한다. -물론 회사에선 까라는대로 해야겠지만....
그럼 파이썬을 통해 AI 를 공부할 나는 어떻게 해야할까??
우선 파이썬은 주로 스네이크 표기법을 따른다.
또한 파이썬의 창시자인 귀도 반 로썸 형님이 작성한 PEP(Python Enhance Proposal) 에 작성한 권장사항이 있는데
PEP 란 파이썬을 개선하기 위한 개선 제안서로써 3가지로 구분된다.
- Standard Track : 파이썬의 새로운 기능이나 구현을 제안
- Informational : 파이썬의 디자인 이슈나 일반적인 지침을 제안
- Process : 파이썬 커뮤니티에 정보를 제안
이러한 제안 중에서 PEP8 은 파이썬 코딩스타일 가이드라인을 의미하며 정보를 제안하는 Process 에 해당된다.
(파이썬 유저라면 코드를 파이썬 스럽게 작성하기위해, Pythonic 하게 코딩하기 위해 이 PEP8 을 읽어보는걸 추천한다.)
이러한 PEP8 의 대표적인 사항을 요약하자면
Code Lay-out
코드 레이아웃 (배치)
들여쓰기 수준당 4개의 공백(space)을 사용
- (), {}, [] 안에서 연속된 줄들은 파이썬의 암시적인 줄 연결이나 행잉 들여쓰기를 통해 수직으로 정렬해야한다.
- 행잉 들여쓰기를 사용할 때는 첫 번째 줄에 인자를 쓰지 않아야하고,
- 추가적 들여쓰기를 통해 연속된 줄이란 것을 분명히 해야한다.
# 들여쓰기 수준당 4개의 공백(space) 를 사용
def example_function():
x = 10
if x > 5:
print("x는 5보다 큽니다.")
# 암시적인 줄연결과 행잉 들여쓰기
# 좋은 예: 첫 번째 줄에 인자를 넣지 않고 행잉 들여쓰기 적용
my_list = [
1, 2, 3,
4, 5, 6,
]
my_dict = {
"name": "Alice",
"age": 30,
"city": "Wonderland",
}
# 함수 호출에서도 같은 규칙 적용
result = my_function(
first_argument,
second_argument,
third_argument,
)
# 첫 번째 줄에 인자를 쓰지 않아야 함
# 나쁜 예
result = my_function(first_argument,
second_argument,
third_argument)
# 좋은 예
result = my_function(
first_argument,
second_argument,
third_argument,
)
탭(Tab) 을 쓸까 공백(Space)을 쓸까
- 공백이 들여쓰기 방법으로 선호된다.
- 탭은 이미 탭으로 들여쓰기된 코드와의 일관성을 위해 사용되어야 한다
- Python 3 은 들여쓰기를 위한 탭과 공백의 혼합을 허용하지 않는다
# 좋은 예 (스페이스 4칸 사용)
def my_function():
x = 10
y = 20
return x + y
# 나쁜 예 (탭 사용)
def my_function():
x = 10
y = 20
return x + y
최대 줄 길이
- 모든 줄은 최대 79자로 제한한다
- docstring 또는 주석과 같이 구조적 제한이 적은 긴 텍스트 블록은 72자로 제한한다
- 긴 코드는 \ 나 괄호를 사용하여 여러 줄로 나눈다
# 좋은 예 (괄호로 묶어서 줄 나눔)
def calculate_sum(a, b, c, d):
return (a + b +
c + d)
# 나쁜 예 (한 줄이 너무 길음)
def calculate_sum(a, b, c, d): return a + b + c + d
줄바꿈은 이전 연산자의 앞에서 한다
- 연산자의 뒤에서 줄바꿈 하면 피연산자와 연산자가 멀리 떨어지게 된다
- 연산자의 앞에서 줄바꿈하면 더 읽기 좋은 코드가 된다.
# 좋은 예
total = (first_value
+ second_value
+ third_value)
# 나쁜 예
total = (first_value +
second_value +
third_value)
# 좋은 예
if (condition_a
and condition_b
or condition_c):
do_something()
# 나쁜 예
if (condition_a and
condition_b or
condition_c):
do_something()
빈 줄 사용
- 최상위 함수와 클래스 정의는 두 개의 빈 줄로 둘러싼다
- 클래스 내부의 메소드 정의는 하나의 빈 줄로 둘러싼다
- 추가 빈 줄은 관련된 함수들의 그룹을 분리하기 위해 아껴서 사용할 수 있다
# 좋은 예
class MyClass:
pass
def my_function():
pass
# 나쁜 예
class MyClass:
pass
def my_function():
pass
임포트 순서 (Imports Order)
- 표준 라이브러리, 서드파티, 로컬 모듈 순으로 구분해 임포트하며 각 그룹 사이에 빈 줄을 둡니다.
# 좋은 예
import os
import sys
import numpy as np
from my_module import my_function
# 나쁜 예 (구분 없이 섞여 있음)
import numpy as np
from my_module import my_function
import os, sys
문자열 따옴표 일관성 (Consistent Quotation Marks)
- 코드 전반에 걸쳐 일관되게 한 가지 스타일의 따옴표를 사용합니다. 일반적으로 " 또는 ' 중 하나로 통일
# 좋은 예
my_string = "Hello, World!"
# 나쁜 예 (따옴표 혼용)
my_string = 'Hello, World!"
표현식과 명령문에서의 공백(WhiteSpace in Expressions and Statements)
공백을 추가하는 것을 피해야 하는 상황
1. (). {}, [] 바로 안쪽
# 좋은 예
my_list = [1, 2, 3]
my_dict = {"key": "value"}
my_tuple = (1, 2, 3)
# 나쁜 예
my_list = [ 1, 2, 3 ]
my_dict = { "key": "value" }
my_tuple = ( 1, 2, 3 )
2. 쉼표, 세미콜론, 콜론 바로 앞
# 좋은 예
print("Hello, world!")
my_dict = {"name": "Alice", "age": 30}
# 나쁜 예
print("Hello , world !")
my_dict = {"name" : "Alice" , "age" : 30 }
3. 연산자 양쪽에 불피요한 공백을 두지 않음
# 좋은 예
x = 5
y = x + 3
# 나쁜 예
x = 5
y = x + 3
4. 함수 호출시 괄호 앞에 공백을 두지 않음
# 좋은 예
result = my_function(1, 2)
# 나쁜 예
result = my_function (1, 2)
5. 리스트 인덱싱과 슬라이싱에서 연속된 공백 사용을 피함
# 좋은 예
value = my_list[1]
subset = my_list[1:4]
# 나쁜 예
value = my_list[ 1 ]
subset = my_list[ 1 : 4 ]
다음 연산자들은 항상 단일 공백으로 둘러싸야한다
- 대입연산자, 복합대입연산자 (=, +=, -= 등)
- 비교 연산자 (==, <, <=, >, >=, is, in 등)
- 논리 연산자 (and, or, not)
우선 순위가 다른 연산자들을 사용하는 경우 우선순위가 낮은 연산자 주위에 공백을 사용해야 한다.
연산자의 양쪽에 같은 개수의 공백을 사용해야 한다.
# 나쁜 예
i=i+1
total +=1
x = x * 2 - 1
result = x * x + y * y
c = (a + b) * (a - b)
# 좋은 예
i = i + 1
total += 1
x = x*2 -1
result = x*x + y*y
c = (a+b) * (a-b)
Naming Conventions
이름짓기 관습
일반적인 네이밍 스타일
- lowercase : 소문자
- lower_case_with_underscores : 밑줄을 포함하는 소문자 (snake_case)
- UPPERCASE : 대문자
- UPPER_CASE_WITH_UNDERSCORES : 밑줄을 포함하는 대문자
- CapitalizedWords : 각 단어의 첫글자는 대문자 (CapWords)
- camelCase : 첫글자는 소문자, 그뒤 각 단어 첫 글자는 대문자
'l' (소문자 엘), 'O' (대문자 오), 'I' (대문자 아이) 는 단일 문자 변수 이름으로 절대 쓰지 않아야 한다.
클래스 이름은 CapWord 표기법을 사용
함수, 메소드, 변수 이름은 snake_case 를 사용
상수는 보통 모듈 수준에서 정의되며 밑줄을 포함하는 대문자를 사용
이러한 사항들이 있다.
이 외에도 대표적으로
- 주석
- 함수와 메서드 컨벤션
- 클래스와 객체 컨벤션
- 파일 및 디렉토리 명명 규칙
- 상수 컨벤션
- 에러 핸들링
등이 있지만 오늘은 코드 컨벤션의 존재 자체를 알았다는 것에 의미를 두고 나중에 알아보며 자기 팀프로젝트에 적용하면 될것이다.
언어별로 조금씩 다른 컨벤션도 있으니 주로 사용하는 언어의 공식 문서에서 권장 컨벤션을 확인하는게 도움이 될것이다.
- Python : PEP 8
- Java : Google Java Style Guide
- C# : Microsoft C# Coding Conventions
등등이 있으니 필요할때 찾아보며 맞춰나가면 더욱 효과적일 것이다.
'개발지식' 카테고리의 다른 글
[Trouble Shooting] 라이브러리 버전호환의 중요성 (5) | 2024.12.30 |
---|---|
판교사투리 (5) | 2024.11.07 |