티스토리 뷰

Python 한글과 영어 예쁘게 정렬(포맷)하는 방법

Intro. 왜 띄어쓰기 제대로 했는데 포맷이 안맞는거지?

product 별로 품목을 정렬해서 출력하려고 했더니 잘되지 않았다.
각 요소 별로 고정된 문자열을 배정하고, 입력 받은 값을 채운 후 나머지 값은 패딩으로 채운 후 출력하도록 했는데 말이다

그 이유는 내가 영어와 한글을 섞어 사용했기 때문에 글자 보폭이 달라서 발생한 문제였다.

해결 방법

class Product:
    def __init__(self, name: str, price: int, quantity: int) -> None:
        self.name = name
        self.price = price
        self.quantity = quantity

    def get_price(self) -> int:
        return self.price * self.quantity

    def __str__(self):
        name_length = 0
        for char in self.name:
            if ord('가') <= ord(char) <= ord('힣'):  # 한글 문자인 경우
                name_length += 2
            else:
                name_length += 1
        # 한글과 영문의 폭을 고려하여 공백을 채워줍니다.
        padding = ' ' * (30 - name_length)
        info = f'{self.name}{padding}{self.quantity:>3}개 {self.get_price():>7}'
        return info

이렇게 구현된 이유는 한글과 영문 문자의 폭이 다르기 때문에 문자열 정렬 시 일관된 정렬을 얻기 위해서입니다.
한글 문자는 대략 영문 문자 2개의 폭에 해당하므로, 이를 고려하여 공백 문자를 적용함으로써 깔끔한 정렬을 구현할 수 있습니다.
이 방식은 정확한 정렬을 위한 대략적인 해결책으로 사용되며, 완벽한 정렬을 원할 경우 폰트에 따른 글자 폭을 계산하는 라이브러리를 사용해야 합니다.

__str__ 메서드는 Product 클래스의 인스턴스를 문자열 형태로 나타내기 위해 사용됩니다. 이 메서드는 다음과 같이 구성되어 있습니다.

  1. name_length 변수를 초기화하여 각 문자의 길이를 저장합니다. 한글과 영문 문자의 길이가 다르기 때문에 이를 고려하여 길이를 계산합니다.
  2. self.name의 각 문자를 반복하며, 한글 문자인 경우 name_length에 2를 더하고, 그렇지 않은 경우(영문, 숫자, 특수문자 등) 1을 더합니다. 이렇게 하여 한글과 영문 문자의 폭을 고려한 이름 길이를 구합니다.
  3. 공백 문자를 사용하여 padding 변수를 생성합니다. padding은 한글과 영문 문자의 폭을 고려하여 self.name 다음에 추가할 공백 문자열입니다. 이때 전체 길이에서 name_length를 빼주어 균일한 길이를 유지합니다.
  4. f-string을 사용하여 최종 문자열을 생성합니다. self.namepadding을 결합하여 이름 부분을 완성한 뒤, 오른쪽 정렬로 수량(self.quantity)와 가격(self.get_price())을 나타냅니다.
728x90