파이썬 (Python)

Python isinstance() 사용시의 주의점

Wibaek 2025. 3. 13. 02:05
728x90

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

What are the differences between type() and isinstance()?

 

What are the differences between type() and isinstance()?

What are the differences between these two code snippets? Using type: import types if type(a) is types.DictType: do_something() if type(b) in types.StringTypes: do_something_else() Using

stackoverflow.com

728x90