PEP 20–The Zen of Python

PEP 20–The Zen of Python 파이썬의 철학과 디자인 원칙을 담고 있다. 파이썬 인터프리터에서 import this를 실행하면 볼 수 있다. 1. Beautiful is Better than Ugly. (아름다움이 추한 것보다 낫다) 코드는 보기 좋고 이해하기 쉽게 작성해야 한다. 1 2 3 4 5 6 7 8 # 아름다운 코드 names = ['Alice', 'Bob', 'Charlie'] for name in names: print(f"Hello, {name}!") # 추한 코드 x=['Alice','Bob','Charlie'] for i in range(len(x)):print("Hello, "+x[i]+"!") 2. Explicit is Better than Implicit. (명시적이 암시적인 것보다 낫다) 코드의 의도를 명확히 표현해야 한다. ...

November 26, 2024 · 6 min · Me

PEP 257–Docstring Conventions

PEP 257–Docstring Conventions Python 코드의 docstring 작성에 대한 규칙과 관례를 정의한 문서 정의 모듈, 함수, 클래스, 메서드 정의의 첫 번째 문장으로 오는 문자열 리터럴로, 해당 객체의 doc 특별 속성이 된다. 작성 대상 모든 모듈, 모듈이 내보내는 모든 함수와 클래스, 공개 메서드(생성자 포함)에 docstring을 작성해야 한다. 형식 항상 """삼중 큰따옴표"""를 사용한다. 한 줄 docstring과 여러 줄 docstring 두 가지 형식이 있다. 한 줄 Docstring 명확한 경우에 사용합니다. 마침표로 끝나는 구문으로 작성합니다. 함수/메서드의 효과를 명령형으로 설명합니다. 여러 줄 Docstring 요약 줄, 빈 줄, 자세한 설명 순으로 구성됩니다. 클래스 docstring 다음에는 빈 줄을 삽입합니다. 기본 규칙 1 2 3 4 5 6 7 def function(arg1, arg2): """한 줄 설명. 여러 줄에 걸친 자세한 설명. 매개변수와 반환값 설명. """ pass 모듈, 함수, 클래스별 Docstring 내용 모듈 내보내는 클래스, 예외, 함수 등을 나열 ...

November 26, 2024 · 2 min · Me

PEP 3000–Python 3000

PEP 3000–Python 3000 Python 3000 개발 과정과 특징을 설명한다. Python 3000, Python 3.0, Py3k는 모두 같은 프로젝트를 지칭한다. PEP 번호 체계 : 3000-3099는 메타 PEP, 3100-3999는 기능 PEP 타임라인 : Python 2.6과 3.0의 동시 출시 계획을 포함. 호환성과 전환: Python 3.0은 2.x와 하위 호환성이 없다. Python 2.6은 “Py3k 경고 모드"와 일부 3.0 기능을 지원. 2to3 도구를 통해 2.x 코드를 3.0으로 변환할 수 있다. 개발 모델: 2.6과 3.0을 동시 지원하는 프로젝트를 위한 권장 개발 방법을 제시. 구현 언어: Python 3000은 C로 구현되며, Python 2 코드베이스에서 진화합니다. Python2와 Python3의 비교 문법 차이 기능 Python 2 Python 3 print문 print "Hello" print("Hello") 정수 나눗셈 5/2 → 2 5/2 → 2.5 예외 처리 except Error, e except Error as e range 리스트 반환 이터레이터 반환 문자열 포맷팅 % 연산자 중심 f-strings, format() 메서드 유니코드 표현 방식 항목 Python 2 Python 3 기본 문자열 ASCII Unicode (UTF-8) 유니코드 선언 u"문자열" 기본 지원 바이트 문자열 str bytes 인코딩 처리 명시적 처리 필요 자동 처리 국제화 지원 제한적 완전 지원 성능 차이 항목 Python 2 Python 3 실행 속도 기준 10-15% 향상 메모리 관리 GC 기본 향상된 GC 멀티스레딩 GIL 제한 GIL 개선 비동기 처리 제한적 async/await 지원 최적화 기본 향상된 최적화 메모리 사용량 차이 항목 Python 2 Python 3 기본 객체 크기 기준 20-30% 감소 문자열 처리 더 많은 메모리 최적화된 메모리 컬렉션 리스트 중심 메모리 효율적인 뷰 캐시 처리 기본 향상된 캐시 메모리 해제 덜 효율적 더 효율적 5. 파일 입출력 성능 차이 항목 Python 2 Python 3 기본 I/O 상대적 느림 15-20% 향상 텍스트 처리 ASCII 중심 유니코드 최적화 버퍼링 기본 향상된 버퍼링 비동기 I/O 제한적 완전 지원 대용량 파일 처리 제한적 효율적 처리 라이브러리 지원 차이 특징 Python 2 Python 3 표준 라이브러리 기본적인 모듈 제공 개선된 모듈 및 새로운 모듈 추가 (예: asyncio, statistics) 서드파티 라이브러리 지원 일부 레거시 라이브러리만 지원 대부분의 주요 라이브러리가 지원 (예: TensorFlow, PyTorch) 새로운 라이브러리 개발 거의 없음 활발히 진행 중 유니코드 관련 라이브러리 제한적 지원 향상된 지원 레거시 라이브러리 호환성 높음 일부 호환되지 않을 수 있음 라이브러리 업데이트 빈도 낮음 (지원 종료) 높음 (지속적인 개선) AI/ML 라이브러리 지원 제한적 광범위 웹 개발 프레임워크 일부 구버전만 지원 최신 버전 지원 (예: Django, Flask) 데이터 과학 라이브러리 제한적 지원 폭넓은 지원 (예: pandas, numpy 최신 버전) 보안 관련 라이브러리 업데이트 중단 지속적인 보안 업데이트 참고 및 출처

November 26, 2024 · 2 min · Me

PEP 3333–Python Web Server Gateway Interface V1.0.1

PEP 3333–Python Web Server Gateway Interface V1.0.1 Python Web Server Gateway Interface (WSGI) 버전 1.0.1을 정의한 문서. PEP 333의 개정판으로, Python 3 지원을 개선하고 몇 가지 오랜 de facto 수정사항을 반영 PEP 3333은 PEP 333을 Python 3 시대에 맞게 업데이트한 버전이다. 주요 변경사항과 특징 Python 3 지원: 문자열 처리가 유니코드로 변경됨 environ 딕셔너리의 문자열은 str 타입이어야 함 응답 본문은 bytes 타입이어야 함 새로운 보안 고려사항: 헤더 인젝션 방지 안전한 문자열 처리 미들웨어 체이닝: 여러 미들웨어를 연결하여 요청/응답 처리 파이프라인 구성 가능 파일 핸들링: wsgi.input과 wsgi.errors를 통한 표준화된 입출력 처리 WSGI (Web Server Gateway Interface) 웹 서버와 Python 웹 어플리케이션 또는 프레임워크 간의 표준 인터페이스를 정의한다. ...

November 26, 2024 · 5 min · Me

PEP 484–Type Hints

PEP 484–Type Hints Python에 타입 힌트(Type Hints)를 도입하여 함수의 인자와 반환값에 대한 타입을 명시할 수 있도록 하는 표준을 정의 Python 3.5부터 도입됨. 코드의 가독성을 높이고 정적 타입 분석 도구가 코드를 검사할 수 있도록 돕는다. PEP 484는 Python의 동적 타이핑 특성을 유지하면서, 타입 힌트를 통해 코드의 품질과 유지보수성을 향상시키는 것을 목표로 한다. 주요 내용 함수 주석을 통한 타입 힌트 함수 인자와 반환값에 대한 타입 정보를 제공하여 코드의 의도를 명확히 한다. 예를 들어, 문자열을 인자로 받고 문자열을 반환하는 함수는 다음과 같이 정의할 수 있다. 1 2 3 4 def greeting(name: str) -> str: return 'Hello ' + name` # `name: str`: `name` 인자는 문자열이어야 함을 나타냅니다. # `-> str`: 함수가 문자열을 반환함을 나타냅니다. 정적 타입 검사 타입 힌트는 런타임에 강제되지 않으며, 정적 분석 도구(예: mypy)를 사용하여 코드의 타입 일관성을 검사할 수 있다. 이는 코드 작성 시 오류를 미리 발견하고 수정할 수 있게 도와준다. 타입 힌트 모듈 typing 모듈을 통해 다양한 타입 힌트를 제공한다. 예를 들어, 리스트, 딕셔너리와 같은 컨테이너 타입 및 제네릭(Generic) 타입을 지원한다. 유연한 사용 타입 힌트는 선택 사항이며, Python은 여전히 동적 타이핑 언어로 남아 있다. 즉, 모든 함수에 타입 힌트를 추가할 필요는 없다. 예제 간단한 예시 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 # 1. 기본적인 타입 힌트 사용 def greeting(name: str) -> str: # name 파라미터는 문자열(str) 타입이어야 함을 나타냄 # -> str 은 함수가 문자열을 반환함을 나타냄 return f"Hello, {name}!" # 2. 여러 기본 타입들의 사용 def calculate_total(quantity: int, price: float) -> float: # quantity는 정수(int), price는 실수(float) 타입 # 반환값은 실수(float) 타입 return quantity * price # 3. 리스트 타입 힌트 사용 from typing import List def get_first_name(names: List[str]) -> str: # names는 문자열 리스트임을 나타냄 # List[str]은 모든 요소가 문자열인 리스트를 의미 return names[0] if names else "" # 4. 옵셔널 타입 사용 from typing import Optional def find_user(user_id: Optional[int]) -> Optional[str]: # user_id는 정수이거나 None일 수 있음을 나타냄 # 반환값도 문자열이거나 None일 수 있음 if user_id is None: return None return f"User_{user_id}" 복잡한 예시 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 30 31 32 33 34 from typing import Dict, Tuple, Union, Callable # 5. 딕셔너리와 복합 타입 def process_user_data( user_info: Dict[str, Union[str, int]] ) -> Tuple[str, int]: # Dict[str, Union[str, int]]는 # - 키는 문자열이고 # - 값은 문자열 또는 정수인 딕셔너리를 의미 # Tuple[str, int]는 문자열과 정수로 구성된 튜플을 반환한다는 의미 name = user_info.get("name", "") age = user_info.get("age", 0) return name, age # 6. 함수 타입 힌트 def apply_operation( func: Callable[[int, int], int], x: int, y: int ) -> int: # Callable[[int, int], int]는 # - 두 개의 정수를 입력받고 # - 정수를 반환하는 함수를 의미 return func(x, y) # 7. 제네릭 타입 from typing import TypeVar, Sequence T = TypeVar('T') # 제네릭 타입 변수 정의 def first_element(sequence: Sequence[T]) -> Optional[T]: # Sequence[T]는 임의의 타입 T로 이루어진 시퀀스를 의미 # Optional[T]는 T 타입 또는 None을 반환할 수 있음을 의미 return sequence[0] if sequence else None 참고 및 출처

November 26, 2024 · 3 min · Me

PEP 492–Coroutines with Async and Await Syntax

PEP 492–Coroutines with Async and Await Syntax Python에 비동기 프로그래밍을 위한 async와 await 구문을 도입하여 코루틴(coroutine)을 명시적으로 정의하고 사용하는 방법을 제안한다. Python 3.5부터 도입되었다. 기존의 제너레이터 기반 코루틴과 구분되는 네이티브 코루틴을 정의한다. PEP 492는 비동기 프로그래밍을 더 명확하고 Pythonic하게 만들어 준다. PEP 492의 주요 내용 네이티브 코루틴 정의 async def 키워드를 사용하여 네이티브 코루틴을 정의한다. 이는 함수가 코루틴임을 명확히 나타내며, 기존의 yield나 yield from 대신 await를 사용한다. 1 2 3 4 async def fetch_data(): """데이터를 비동기적으로 가져오는 네이티브 코루틴""" await asyncio.sleep(1) # 비동기 작업 대기 return "data" await 표현식 await 키워드는 코루틴에서 다른 코루틴이나 비동기 작업의 완료를 기다릴 때 사용된다. ...

November 26, 2024 · 4 min · Me

PEP 8-Style Guide for Python Code

PEP8 - Style Guide for Python Code Python 코드의 스타일 가이드로, 가독성과 일관성을 높이기 위한 다양한 규칙과 권장사항을 제시한다. 중요한 점은 이 가이드라인들은 제안사항이며, 프로젝트의 일관성이 더 중요하다. 기존 코드의 스타일을 존중해야 한다. 일부 규칙은 특수한 상황에서 무시될 수 있다. 가독성이 최우선. 프로젝트별로 자체적인 스타일 가이드가 있을 경우 해당 가이드를 우선시 코드 레이아웃 (Code Layout) 들여쓰기 (Indentation) 4개의 스페이스를 사용. 연속된 줄은 괄호 안에서 수직으로 정렬하거나 hanging indent를 사용한다. 탭은 사용하지 않음. 탭과 공백은 혼용하지 않는다. 라인 길이 최대 79자 문서화 문자열(docstring)과 주석은 72자 긴 줄은 여러 줄로 나누어 작성. 줄 연결은 괄호나 백슬래시를 사용한다. 줄바꿈 연산자 앞에서 줄을 바꾸는 것이 더 가독성이 좋다. 올바른 예 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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 # 괄호 안에서 수직 정렬 foo = long_function_name(var_one, var_two, var_three, var_four) # Hanging indent def long_function_name( var_one, var_two, var_three, var_four): # 함수 내용은 4칸 들여쓰기 print(parameter_1) # if문도 4칸 들여쓰기 if True: # if문 내부는 추가로 4칸 들여쓰기 print("Nested content") # 여러 줄의 리스트 my_list = [ 1, 2, 3, 4, 5, 6 ] with open('/path/to/some/file/you/want/to/read') as file_1, \ open('/path/to/some/file/being/written', 'w') as file_2: file_2.write(file_1.read()) # 1. 괄호를 사용한 줄 나누기 long_string = ( "이것은 매우 긴 문자열이라서 " "여러 줄로 나누어 작성했습니다." ) # 2. 연산자 앞에서 줄 바꾸기 total = ( first_variable + second_variable - third_variable ) income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest) # 3. 함수 인자 나누기 def long_function_name( var_one, var_two, var_three, var_four): print(var_one) 잘못된 예 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 30 31 32 33 34 35 # 인자가 첫 줄에 있으면 안 됨 foo = long_function_name(var_one, var_two, var_three, var_four) def long_function_name( parameter_1, # 2칸만 들여씀 parameter_2, parameter_3 # 불필요하게 많이 들여씀 ): print(parameter_1) # 탭 사용 if True: print("Wrong indent") # 3칸만 들여씀 with open('/path/to/some/file/you/want/to/read') as file_1, open('/path/to/some/file/being/written', 'w') as file_2: file_2.write(file_1.read()) # 1. 한 줄이 너무 김 long_string = "이것은 매우 긴 문자열이라서 한 줄에 전부 작성하면 79자를 훨씬 넘어가게 되어 가독성이 떨어지게 됩니다." # 2. 잘못된 줄 나누기 total = first_variable + \ second_variable + \ third_variable income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest) # 3. 잘못된 함수 인자 나누기 def long_function_name(var_one, var_two , var_three, var_four): # 쉼표가 잘못된 위치에 있음 print(var_one) 임포트 (Import) 임포트는 항상 파일의 맨 위에 작성한다. 각 임포트는 별도의 줄에 작성한다. 임포트는 다음 순서로 그룹화한다. 표준 라이브러리 관련된 서드파티 라이브러리 로컬 애플리케이션 / 라이브러리 올바른 예 1 2 3 4 5 6 7 8 9 10 11 12 13 # 1. 표준 라이브러리 import os import sys from datetime import datetime, timedelta # 2. 서드파티 라이브러리 import numpy as np import pandas as pd # 3. 로컬 애플리케이션 from myproject.models import User from myproject.utils import helper from . import localmodule 잘못된 예 1 2 3 4 5 6 7 8 9 10 11 12 13 # 1. 한 줄에 여러 임포트 import sys, os, datetime # 2. 잘못된 순서 from myproject.models import User import os import pandas as pd # 3. 와일드카드 임포트 from mymodule import * # 이것은 피해야 함 # 4. 불필요한 임포트 from mymodule import MyClass, MyClass # 중복 표현식과 문장의 공백 적절한 공백 사용은 코드의 가독성을 크게 향상시킨다. 일관된 공백 사용이 중요하다. 괄호, 대괄호, 중괄호 안쪽에 불필요한 공백을 넣지 않는다. 쉼표, 세미콜론, 콜론 앞에는 공백을 넣지 않는다. 올바른 예 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # 1. 할당 연산자 x = 1 y = 2 # 2. 연산자 result = x + y * (z - 1) # 3. 쉼표 후 공백 items = [1, 2, 3, 4, 5] def func(x, y, z): pass if x == 4: print(x, y); x, y = y, x # 1. 괄호 spam(ham[1], {eggs: 2}) # 2. 딕셔너리 dict = {'key': 'value'} # 3. 리스트/튜플 list = [1, 2, 3] tuple = (1, 2, 3) 잘못된 예 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 1. 불일치하는 공백 x=1 y= 2 z =3 # 2. 연산자 주변 공백 누락 result=x+y*(z-1) # 3. 쉼표 후 공백 누락 items = [1,2,3,4,5] def func(x,y,z): pass if x == 4 : print(x , y) ; x , y = y , x # 1. 불필요한 공백 spam( ham[ 1 ], { eggs: 2 } ) # 2. 불일치하는 공백 dict = { 'key':'value' } dict = {'key' :'value'} # 3. 리스트/튜플의 불필요한 공백 list = [ 1,2,3 ] tuple = ( 1,2,3 ) 명명 규칙(Naming Conventions) 일관된 이름 규칙은 코드의 가독성을 높인다. 의미 있고 설명적인 이름을 사용해야 한다. 타입 규칙 예시 설명 패키지/모듈 짧은 소문자 필요시 언더스코어 utils email_validator data_parser 모듈은 import 시 파일명이 되므로 짧고 간단하게 작성 클래스 CapWords(Pascal Case) UserProfile EmailValidator DatabaseConnection 각 단어의 첫 글자를 대문자로 작성 함수/메서드 소문자 + 언더스코어 (snake_case) calculate_total() get_user_info() validate_email() 기능을 명확히 설명하는 동사로 시작 변수 소문자 + 언더스코어 (snake_case) user_name total_count items_list 데이터의 내용을 명확히 설명 상수 대문자 + 언더스코어 MAX_VALUE DEFAULT_TIMEOUT PI 변경되지 않는 값임을 명확히 표시 보호 속성 앞에 언더스코어 1개 _internal_name _protected_method() 직접 접근을 권장하지 않는 내부 사용 속성 비공개 속성 앞에 언더스코어 2개 __private_name __private_method() 클래스 외부에서 접근을 제한하는 속성 특별 메서드 앞뒤 더블 언더스코어 __init__ __str__ __len__ Python에서 특별한 의미를 가진 메서드 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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 # 1. 패키지/모듈 예시 import email_validator from data_processing import utils # 2. 클래스 예시 class UserProfile: def __init__(self, name): self.name = name class EmailValidator: def validate(self, email): pass # 3. 함수/메서드 예시 def calculate_total(items): return sum(items) def get_user_info(user_id): pass # 4. 변수 예시 first_name = "John" total_count = 0 items_list = [] # 5. 상수 예시 MAX_CONNECTIONS = 100 DEFAULT_TIMEOUT = 30 PI = 3.14159 # 6. 클래스에서의 보호/비공개 속성 예시 class Customer: def __init__(self): self._internal_id = 123 # 보호 속성 self.__private_data = "secret" # 비공개 속성 def _protected_method(self): # 보호 메서드 pass def __private_method(self): # 비공개 메서드 pass def __str__(self): # 특별 메서드 return f"Customer {self._internal_id}" 추가적인 명명 규칙 지침: ...

November 26, 2024 · 22 min · Me