덕 타이핑

컴퓨터 프로그래밍 분야에서 덕 타이핑(duck typing)은 동적 타이핑의 한 종류로, 객체의 변수 및 메소드의 집합이 객체의 타입을 결정하는 것을 말한다. 클래스 상속이나 인터페이스 구현으로 타입을 구분하는 대신, 덕 타이핑은 객체가 어떤 타입에 걸맞은 변수와 메소드를 지니면 객체를 해당 타입에 속하는 것으로 간주한다. “덕 타이핑”이라는 용어는 다음과 같이 표현될 수 있는 덕 테스트에서 유래했다. (덕은 영어로 오리를 의미한다.)
만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라고 부를 것이다.
덕 타이핑에서는, 객체의 타입보다 객체가 사용되는 양상이 더 중요하다. 예를 들면, 덕 타이핑이 없는 프로그래밍 언어로는 오리 타입의 객체를 인자로 받아 객체의 걷기 메소드와 꽥꽥거리기 메소드를 차례로 호출하는 함수를 만들 수 있다. 반면에, 같은 함수를 덕 타이핑이 지원되는 언어에서는 인자로 받는 객체의 타입을 검사하지 않도록 만들 수 있다. 걷기 메소드나 꽥꽥거리기 메소드를 호출 할 시점에서 객체에 두 메소드가 없다면 런타임 에러가 발생하고, 두 메소드가 제대로 구현되어 있다면 함수는 정상적으로 작동한다. 여기에는 인자로 받은 객체가 걷기 메소드와 꽥꽥거리기 메소드를 갖고 있다면 객체를 오리 타입으로 간주하겠다는 암시가 깔려있다. 바로 이 점이 앞에서 인용한 덕 테스트의 사상과 일치하기 때문에 덕 타이핑이라는 이름이 붙었다.

예제

다음 덕 타입트(duck typed) 언어의 의사코드이다:
function calculate(a, b, c) => return (a+b)*c
a = calculate (1, 2, 3)
b = calculate ([1, 2, 3], [4, 5, 6], 2)
c = calculate ('apples ', 'and oranges, ', 3)
print to_string a
print to_string b
print to_string c
결과는 다음과 같다:
9
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
apples and oranges, apples and oranges, apples and oranges,

파이썬 예제

class Duck:
        def quack(self): print u"꽥꽥!"
        def feathers(self): print u"오리에게 흰색, 회색 깃털이 있습니다."class Person:
        def quack(self): print u"이 사람이 오리를 흉내내네요."
        def feathers(self): print u"사람은 바닥에서 깃털을 주어서 보여 줍니다."def in_the_forest(duck):
        duck.quack()
        duck.feathers()def game():
        donald = Duck()
        john = Person()
        in_the_forest(donald)
        in_the_forest(john)

C++ 예제

class Duck {public:
    void quack() {
        std::cout << "Quaaaaaack!" << std::endl;
    }
    
    void feathers() {
        std::cout << "The duck has white and gray feathers." << std::endl;
    }}class Person {public:
    void quack() {
        std::cout << "The person imitates a duck." << std::endl;
    }
    
    void feathers() {
        std::cout << "The person takes a feather from the ground and shows it." << std::endl;
    }}template <typename T>void inTheForest(T& t){
    t.quack();
    t.feathers();}int main(){
    Duck donald;
    Person jhon;
    
    inTheForest( donald );
    inTheForest( jhon );}

스몰토크

객체 지향 언어인 스몰토크는 변수나 메소드 인자에 대한 형 선언이 없으므로, 당연히 덕 타이핑을 지원하고 있다. 스몰토크에서는 동일한 프로토콜(protocol)을 구현하는 클래스들은 보통 동일한 상속 계층에 속하나, 꼭 그럴 필요는 없다.

파이썬

파이썬에서 덕 타이핑은 매우 많이 쓰이고 있다. 파이썬 튜터리얼의 용어 항목은 덕 타이핑을 다음과 같이 설명하고 있다:
Pythonic programming style that determines an object's type by inspection of its method or attribute signature rather than by explicit relationship to some type object ("If it looks like a duck and quacks like a duck, it must be a duck.") By emphasizing interfaces rather than specific types, well-designed code improves its flexibility by allowing polymorphic substitution. Duck-typing avoids tests using type() or isinstance(). Instead, it typically employs hasattr() tests or EAFP (Easier to Ask Forgiveness than Permission) programming.
객체의 타입을 다른 타입 객체와의 명시적인 관계를 비교하는 것이 아니라, 그 객체의 메서드나 속성들을 비교함으로써 판별하는 파이썬적인 프로그래밍 스타일이다. (“오리처럼 보이고, 오리처럼 운다면 오리임에 틀림없다.”) 특정 타입 대신 인터페이스를 강조함으로써, 잘 디자인된 코드는 다형적 대체를 허용함으로써 유연성을 향상시킬 수 있다. 덕 타이핑을 이용하면 type()이나 isinstance()를 이용한 테스트를 하지 않는다. 대신, 대개 hasattr() 테스트를 이용하거나, 혹은 EAFP (Easier to ask forgiveness than permission; 하고 나서 용서를 비는 것이 하기 전에 허락을 구하는 것보다 쉽다) 프로그래밍 기법을 이용한다.