isinstance() 사용시의 주의점

Published
January 21, 2025
Last updated
Last updated January 21, 2025
Tistory
Category
Tags

isinstance()

파이썬에는 isinstance() 라는 인스턴스가 특정 클래스/데이터 타입인지 검사할 수 있는 메서드가 존재한다. 이는 약타입 언어인 파이썬에서 유용하게 사용될 수 있는 기능이다.
import datetime as dt integer = 1 print(isinstance(integer, int)) # True today = dt.date.today() print(isinstance(today, dt.date)) # True

date → datetime 변환 로직

해당 isinstance() 메서드를 이용해 date 객체를 datetime으로 변환하는 다음과 같은 로직이 있다.
import datetime as dt def convert_to_datetime(date: dt.date | dt.datetime) -> dt.datetime: if isinstance(date, dt.date): return dt.datetime.combine(date, dt.datetime.max.time()) return date today = dt.date(2025, 1, 1) print(convert_to_datetime(today)) now = dt.datetime(2025, 1, 1, 12, 34, 56) print(convert_to_datetime(now))
위 함수는 datetime또는 date를 받아 만약 시간 정보가 없는 date 객체라면 시간을 23:59:59.999… 로 설정해주는 기능을 한다.
 
만약 의도대로 함수가 작동한다면 결과는 다음과 같이 출력될것이다.
2025-01-01 23:59:59.999999 2025-01-01 12:34:56
그러나 실제로는 다음과 같은 출력을 확인할 수 있다.
2025-01-01 23:59:59.999999 2025-01-01 23:59:59.999999
어째서 이런일이 일어났을까?

isinstance()와 type()의 차이

그것은 바로 isinstance()가 인스턴스와 클래스가 동일할 때만 True를 반환하는 것이 아닌, instance가 클래스의 subclass 일때도 True를 반환하기 떄문이다.
datetime 클래스를 다시 살펴보면
class datetime(date): ...
다음과 같이 date를 상속받고 있다는 것을 알 수 있다.
isinstance(datetime, date) 를 했을 때 False를 기대했지만 실제로는 datetime이 date를 상속하기 때문에 True가 리턴되어 문제가 발생한 것이다.
 
이럴 때는 isinstance()가 아닌 type()을 이용해 직접 비교를 해줄 수 있다.
def convert_to_datetime(date: dt.date | dt.datetime) -> dt.datetime: if type(date) is dt.date: return dt.datetime.combine(date, dt.datetime.max.time()) return date
의도된 대로 작동하는 것을 확인할 수 있다.
2025-01-01 23:59:59.999999 2025-01-01 12:34:56

Reference