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