이 글 공유하기

이메일FacebookRedditWhatsApp

파이썬 덕 타이핑 정리

#python#duck-typing#dev

덕 타이핑은 객체의 실제 클래스보다 필요한 메서드나 속성을 가지고 있는지를 기준으로 객체를 다루는 방식이다. 파이썬에서는 특정 타입인지 먼저 검사하기보다, 필요한 동작을 호출해 보고 사용할 수 있는지를 중심으로 코드를 작성하는 경우가 많다.

덕 타이핑(duck typing)은 파이썬에서 객체와 클래스를 학습하다 보면 등장하는 용어이다. 이 이름은 “If it walks like a duck, and quacks like a duck, it is a duck” (만약 그것이 오리처럼 걷고, 오리처럼 꽥꽥 소리를 내면, 그것은 오리라고 봐도된다.)의 오래된 표현에서 유래한 것으로 알려져 있다. 즉, 프로그래밍상에서 덕 타이핑은 객체가 어떤 클래스에서 만들어졌는지보다, 필요한 기능을 가지고 있는지를 더 중요하게 보는 방식이다. 필요한 기능을 가지고 있으면 그 타입처럼 써도 된다 라는 의미이기도 하다. 파이썬에서는 유명하지만, 원래는 동적 타입 언어 전반에서 흔한 사고 방식이다.

예시로 알아보자.

먼저 강아지와 고양이 클래스가 있다.

class Dog:
    def sound(self):
        return "멍멍"

class Cat:
    def sound(self):
        return "야옹"

class Robot:
    def sound(self):
        return "삐빅"

class Car:
    def drive(self):
        return "부릉부릉"

def make_sound(obj):
    # 여기서 obj가 Dog인지, Cat인지, Robot인지 확인하지 않는다.
    # 중요한 것은 obj가 sound() 기능을 가지고 있느냐다.
    print(obj.sound())

dog = Dog()
cat = Cat()
robot = Robot()

make_sound(dog)     # 멍멍
make_sound(cat)     # 야옹
make_sound(robot)   # 삐빅

# Dog, Cat, Robot은 서로 다른 클래스이다.
# 다만, 모두 같은 sound() 메서드를 가지고 있기 때문에
# make_sound() 함수에서 같은 방식으로 사용할 수 있다.

car = Car()
# make_sound(car) 에러 발생
# AttributeError: 'Car' object has no attribute 'sound'

위 코드에서 make_sound() 함수는 객체가 Dog인지, Cat인지, Robot인지 확인하지 않는다. 대신 sound() 메서드를 사용할 수 있는지만 본다. Dog, Cat, Robot은 서로 다른 클래스이지만 모두 sound() 메서드를 가지고 있기 때문에 같은 함수에서 사용할 수 있다.

덕 타이핑을 처음 보면 “그냥 메서드가 있으면 쓰는 거 아닌가? 너무 당연한 거 아닌가?”라고 느낄 수 있다. 사실 파이썬만 사용하다 보면 이 개념이 별로 특별하거나 중요하지 않게 느껴질 수도 있다.

하지만 덕 타이핑의 핵심은 바로 그 “당연해 보이는 방식”에 있다. 덕 타이핑은 isinstance(obj, Duck)처럼 객체가 특정 클래스인지 먼저 확인하는 방식이 아니다. 대신 obj.quack()처럼 내가 필요한 기능을 실제로 사용할 수 있는지를 보고 객체를 다루는 방식이다.

즉, “이 객체가 Duck 클래스인가?”를 묻기보다 “이 객체가 quack()을 할 수 있는가?”를 보는 것이다. 파이썬에서는 이런 방식이 자연스러운 특성 중 하나이다.

isinstance()는 어떤 객체가 특정 클래스/타입으로 만들어졌는지 확인하는 함수.

x = 10

print(isinstance(x,int))    # True
print(isinstance(x, str))   # False

items = [1,2,3]

print(isinstance(items, list))  # True

class Animal:
    pass

class Dog(Animal):
    pass

dog = Dog()

print(isinstance(dog, Dog))     # True
# 상속 관계도 인식한다.
print(isinstance(dog, Animal))  # True

덕 타이핑은 파이썬 코드가 유연하게 동작할 수 있게 해주는 중요한 사고 방식이다. 다만 필요한 메서드가 없으면 실행 시점에 오류가 나기 때문에, 어떤 동작을 기대하는지 함수 이름과 예외 처리로 명확하게 드러내는 것이 좋다.