Saturday, December 6, 2014

Duck Typing and Interfaces

In a dynamically typed language, where type is inferred at runtime, we can get away with using the same method to process different variable types. This enables and encourages us to program against an interface rather than implementation. The following code demonstrates duck typing in Python.

def add(a, b):
  return a+b

result1 = add(50, 25)
result2 = add([0, 1, 2], [3, 4, 5])
result3 = add('Berlin, ', 'Germany')

print result1
# 75

print result2
# [0, 1, 2, 3, 4, 5]

print result3
# Berlin, Germany

Interfaces

Here's another example that focuses more on designing methods as interfaces, allowing the types, or base classes, of the parameters to remain ambiguous.

def iterate_through(f):
  for lineNo, line in enumerate(f):
    print "{0:03d} {1}".format(lineNo, line.rstrip())

iterate_through(infile)
# 001 ANVIL
# 002 FELIX
# 003 LEVER
# 004 SCIMITAR

iterate_through(['ANVIL', 'FELIX', 'LEVER', 'SCIMITAR'])
# 001 ANVIL
# 002 FELIX
# 003 LEVER
# 004 SCIMITAR

So whether you're passing in a file or a list, the enumerate method accepts any iterable, so the function will still work. So in Python, an interface is a system that provides certain methods without conforming to a certain type. Here's a final example that demonstrates duck typing with classes.

class Duck:
  def quack(self):
    print "Quack!"
  def walk(self):
    print "Waddle."
 
class Rabbit:
  def quack(self):
    print "I'm Quacking!"
  def walk(self):
    print "I'm Waddling!"
 
def spring(mallard):
  mallard.quack()
  mallard.fly()
 
spring(Duck())
# Quack!
# Waddle.

spring(Person())
# I'm quacking!
# I'm waddling!

No comments:

Post a Comment