Ch 2.4 형변환(Type Casting)
형변환은 하나의 데이터 타입을 다른 타입으로 변환하는 과정입니다. 파이썬은 암시적 형변환과 명시적 형변환을 모두 지원합니다.
1. 암시적 형변환
파이썬이 자동으로 타입을 변환합니다. 주로 숫자 연산에서 발생합니다.
# int + float → float (자동 변환)
result = 5 + 2.0
print(result) # 7.0
print(type(result)) # <class 'float'>
# int + bool → int (bool이 int의 서브클래스)
result2 = 10 + True
print(result2) # 11
print(type(result2)) # <class 'int'>
result3 = 10 + False
print(result3) # 10
# int + complex → complex
result4 = 3 + (2 + 1j)
print(result4) # (5+1j)
print(type(result4)) # <class 'complex'>
# 암시적 변환 우선순위: complex > float > int
파이썬은 데이터 손실이 발생할 수 있는 변환은 암시적으로 하지 않습니다. 예를 들어
float + str은 TypeError가 발생합니다.
# 이것은 에러 — 암시적 변환 없음
# result = 5 + "10" # TypeError: unsupported operand type(s) for +: 'int' and 'str'
2. 명시적 형변환
개발자가 직접 타입을 변환합니다.
int() 변환
# float → int (소수점 버림, 반올림 아님!)
print(int(3.9)) # 3 (버림!)
print(int(-3.9)) # -3 (버림, 절댓값 기준)
print(int(3.1)) # 3
# str → int
print(int("42")) # 42
print(int(" 100 ")) # 100 (앞뒤 공백 자동 제거)
# bool → int
print(int(True)) # 1
print(int(False)) # 0
# 진수 변환 (문자열에서)
print(int("1010", 2)) # 10 (2진수 "1010" → 정수 10)
print(int("ff", 16)) # 255 (16진수 "ff" → 정수 255)
print(int("17", 8)) # 15 (8진수 "17" → 정수 15)
float() 변환
# int → float
print(float(42)) # 42.0
# str → float
print(float("3.14")) # 3.14
print(float("1e3")) # 1000.0
print(float("inf")) # inf
print(float("-inf")) # -inf
print(float("nan")) # nan
# bool → float
print(float(True)) # 1.0
str() 변환
# 모든 타입 → 문자열
print(str(42)) # '42'
print(str(3.14)) # '3.14'
print(str(True)) # 'True'
print(str(None)) # 'None'
print(str([1, 2, 3])) # '[1, 2, 3]'
print(str({"a": 1})) # "{'a': 1}"
bool() 변환
# 다양한 타입 → bool
print(bool(1)) # True
print(bool(0)) # False
print(bool(-1)) # True (0이 아니면 True)
print(bool("hello")) # True
print(bool("")) # False (빈 문자열)
print(bool([1, 2])) # True
print(bool([])) # False (빈 리스트)
print(bool(None)) # False
print(bool({})) # False (빈 딕셔너리)
print(bool({0})) # True (0이 있는 집합 — 비어있지 않음)
list(), tuple(), set() 변환
# 상호 변환
my_list = [1, 2, 3, 3, 2]
my_tuple = tuple(my_list) # (1, 2, 3, 3, 2)
my_set = set(my_list) # {1, 2, 3} (중복 제거)
print(list(my_tuple)) # [1, 2, 3, 3, 2]
print(list(my_set)) # [1, 2, 3] (순서 비결정)
# 문자열 → 리스트 (각 문자가 요소)
chars = list("Python")
print(chars) # ['P', 'y', 't', 'h', 'o', 'n']
# range → 리스트
numbers = list(range(1, 11))
print(numbers) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 딕셔너리 → 리스트 (키 목록)
d = {"a": 1, "b": 2, "c": 3}
print(list(d)) # ['a', 'b', 'c'] (키)
print(list(d.values())) # [1, 2, 3] (값)
print(list(d.items())) # [('a', 1), ('b', 2), ('c', 3)]
3. 문자열 → 숫자 변환 실패 처리
# 변환 실패 시 ValueError 발생
# int("hello") # ValueError: invalid literal for int() with base 10: 'hello'
# float("abc") # ValueError: could not convert string to float: 'abc'
# try/except으로 안전하게 처리
def safe_int(value: str, default: int = 0) -> int:
"""문자열을 정수로 안전하게 변환합니다."""
try:
return int(value)
except (ValueError, TypeError):
return default
print(safe_int("42")) # 42
print(safe_int("hello")) # 0 (기본값)
print(safe_int("3.14")) # 0 (소수점 있으면 실패)
print(safe_int(None)) # 0
def safe_float(value, default=0.0):
try:
return float(value)
except (ValueError, TypeError):
return default
print(safe_float("3.14")) # 3.14
print(safe_float("hello")) # 0.0
# 실전 예시: 사용자 입력 처리
def get_user_age() -> int:
while True:
user_input = input("나이를 입력하세요: ")
try:
age = int(user_input)
if age < 0 or age > 150:
print("올바른 나이를 입력해주세요 (0-150).")
continue
return age
except ValueError:
print(f"'{user_input}'는 유효한 숫자가 아닙니다. 다시 입력해주세요.")
4. Falsy 값 목록
파이썬에서 bool() 변환 시 False로 평가되는 값들입니다.
falsy_values = [
None, # NoneType
False, # bool
0, # int
0.0, # float
0j, # complex
"", # 빈 문자열
b"", # 빈 bytes
[], # 빈 리스트
(), # 빈 튜플
{}, # 빈 딕셔너리
set(), # 빈 집합
]
for val in falsy_values:
print(f"bool({val!r:15}) = {bool(val)}")
# 모두 False 출력됨
# Falsy 활용 패턴
def process_name(name: str | None) -> str:
if not name: # None, "", " ".strip() 결과 "" 모두 처리
return "Anonymous"
return name.strip().title()
print(process_name(None)) # Anonymous
print(process_name("")) # Anonymous
print(process_name("alice")) # Alice
5. 진수 변환
number = 255
# 정수 → 진수 문자열
print(bin(number)) # '0b11111111'
print(oct(number)) # '0o377'
print(hex(number)) # '0xff'
# 접두사 없이 출력
print(format(number, 'b')) # '11111111'
print(format(number, 'o')) # '377'
print(format(number, 'x')) # 'ff'
print(format(number, 'X')) # 'FF' (대문자)
# 자리수 지정
print(format(number, '08b')) # '11111111' (8자리)
print(format(number, '#010b')) # '0b11111111' (접두사 포함 10자리)
# 진수 문자열 → 정수
print(int("11111111", 2)) # 255 (2진수)
print(int("377", 8)) # 255 (8진수)
print(int("ff", 16)) # 255 (16진수)
print(int("FF", 16)) # 255 (대소문자 모두)
print(int("0xff", 16)) # 255 (접두사 포함도 가능)
# 실전: RGB 색상 변환
def hex_to_rgb(hex_color: str) -> tuple[int, int, int]:
"""#RRGGBB 형식을 RGB 튜플로 변환합니다."""
hex_color = hex_color.lstrip('#')
r = int(hex_color[0:2], 16)
g = int(hex_color[2:4], 16)
b = int(hex_color[4:6], 16)
return r, g, b
def rgb_to_hex(r: int, g: int, b: int) -> str:
"""RGB 값을 #RRGGBB 형식으로 변환합니다."""
return f"#{r:02X}{g:02X}{b:02X}"
print(hex_to_rgb("#FF5733")) # (255, 87, 51)
print(rgb_to_hex(255, 87, 51)) # #FF5733
고수 팁:
__int__, __float__, __bool__ 매직 메서드로 커스텀 형변환파이썬의 int(), float(), bool() 함수는 내부적으로 객체의 매직 메서드를 호출합니다. 이를 구현하면 커스텀 클래스도 형변환을 지원할 수 있습니다.
class Temperature:
"""섭씨 온도를 나타내는 클래스"""
def __init__(self, celsius: float):
self.celsius = celsius
def __int__(self) -> int:
"""int() 호출 시 섭씨를 반올림한 정수 반환"""
return round(self.celsius)
def __float__(self) -> float:
"""float() 호출 시 섭씨 반환"""
return float(self.celsius)
def __bool__(self) -> bool:
"""절대영도(0K = -273.15°C) 초과 시 True"""
return self.celsius > -273.15
def __str__(self) -> str:
return f"{self.celsius}°C"
def to_fahrenheit(self) -> float:
return self.celsius * 9 / 5 + 32
temp = Temperature(36.6)
print(int(temp)) # 37
print(float(temp)) # 36.6
print(bool(temp)) # True
freezing = Temperature(-273.15)
print(bool(freezing)) # False (절대영도)
print(str(temp)) # 36.6°C
print(temp.to_fahrenheit()) # 97.88
# 실용적인 예: 금액 클래스
class Money:
def __init__(self, amount: float, currency: str = "KRW"):
self.amount = amount
self.currency = currency
def __int__(self) -> int:
return int(self.amount)
def __float__(self) -> float:
return float(self.amount)
def __bool__(self) -> bool:
return self.amount > 0
def __str__(self) -> str:
return f"{self.amount:,.0f} {self.currency}"
price = Money(29_900)
print(str(price)) # 29,900 KRW
print(bool(price)) # True
print(bool(Money(0))) # False
형변환의 다양한 방법을 이해했습니다. 다음 챕터에서는 파이썬 3.12+에서 더욱 중요해진 타입 힌트(Type Hints)를 알아보겠습니다.