Python - Duck Typing and Asking Forgiveness, Not Permission (EAFP)
** Duck Typing and Asking Forgiveness, Not Permission (EAFP)
==========================================
# Duck Typing and Easier to ask forgiveness than permission (EAFP)
class Duck:
def quack(self):
print('Quack, quack')
def fly(self):
print('Flap, Flap!')
class Person:
def quack(self):
print("I'm Quacking Like a Duck!")
def fly(self):
print("I'm Flapping my Arms!")
def quack_and_fly(thing):
pass
# Not Duck-Typed (Non-Pythonic)
if isinstance(thing, Duck):
thing.quack()
thing.fly()
else:
print('This has to be a Duck!')
print()
d = Duck()
quack_and_fly(d)
p = Person()
quack_and_fly(p)
---------------------------------
Quack, quack
Flap, Flap!
This has to be a Duck!
---------------------------------
==========================================
# Duck Typing and Easier to ask forgiveness than permission (EAFP)
class Duck:
def quack(self):
print('Quack, quack')
def fly(self):
print('Flap, Flap!')
class Person:
def quack(self):
print("I'm Quacking Like a Duck!")
def fly(self):
print("I'm Flapping my Arms!")
def quack_and_fly(thing):
thing.quack()
thing.fly()
print()
d = Duck()
quack_and_fly(d)
p = Person()
quack_and_fly(p)
---------------------------------
Quack, quack
Flap, Flap!
I'm Quacking Like a Duck!
I'm Flapping my Arms!
---------------------------------
==========================================
# Duck Typing and Easier to ask forgiveness than permission (EAFP)
class Duck:
def quack(self):
print('Quack, quack')
def fly(self):
print('Flap, Flap!')
class Person:
def quack(self):
print("I'm Quacking Like a Duck!")
def fly(self):
print("I'm Flapping my Arms!")
def quack_and_fly(thing):
# LBYL (Non-Pythonic)
if hasattr(thing, 'quack'):
if callable(thing.quack):
thing.quack()
if hasattr(thing, 'fly'):
if callable(thing.fly):
thing.fly()
print()
d = Duck()
quack_and_fly(d)
p = Person()
quack_and_fly(p)
---------------------------------
Quack, quack
Flap, Flap!
I'm Quacking Like a Duck!
I'm Flapping my Arms!
---------------------------------
==========================================
# Duck Typing and Easier to ask forgiveness than permission (EAFP)
class Duck:
def quack(self):
print('Quack, quack')
def fly(self):
print('Flap, Flap!')
class Person:
def quack(self):
print("I'm Quacking Like a Duck!")
def fly(self):
print("I'm Flapping my Arms!")
def quack_and_fly(thing):
# EAFP (Pythonic)
try:
thing.quack()
thing.fly()
thing.bark()
except AttributeError as e:
print(e)
print()
d = Duck()
quack_and_fly(d)
p = Person()
quack_and_fly(p)
---------------------------------
Quack, quack
Flap, Flap!
'Duck' object has no attribute 'bark'
I'm Quacking Like a Duck!
I'm Flapping my Arms!
'Person' object has no attribute 'bark'
---------------------------------
==========================================
person = {'name': 'Jess', 'age': 23, 'job': 'Programmer'}
# LBYL (Non-Pythonic)
if 'name' in person and 'age' in person and 'job' in person:
print("I'm {name}. I'm {age} years old and I am a {job}".format(**person))
else:
print("Missing some keys")
---------------------------------
I'm Jess. I'm 23 years old and I am a Programmer
---------------------------------
==========================================
person = {'name': 'Jess', 'age': 23}
# LBYL (Non-Pythonic)
if 'name' in person and 'age' in person and 'job' in person:
print("I'm {name}. I'm {age} years old and I am a {job}".format(**person))
else:
print("Missing some keys")
---------------------------------
Missing some keys
---------------------------------
==========================================
person = {'name': 'Jess', 'age': 23, 'job': 'Programmer'}
# EAFP (Pythonic)
try:
print("I'm {name}. I'm {age} years old and I am a {job}".format(**person))
except KeyError as e:
print("Missing {} key".format(e))
---------------------------------
I'm Jess. I'm 23 years old and I am a Programmer
---------------------------------
==========================================
person = {'name': 'Jess', 'age': 23}
# EAFP (Pythonic)
try:
print("I'm {name}. I'm {age} years old and I am a {job}".format(**person))
except KeyError as e:
print("Missing {} key".format(e))
---------------------------------
Missing 'job' key
---------------------------------
==========================================
my_list = [1, 2, 3, 4, 5, 6]
# Non-Pythonic
if len(my_list) >= 6:
print(my_list[5])
else:
print("That index does not exist")
---------------------------------
6
---------------------------------
==========================================
my_list = [1, 2, 3, 4, 5]
# Non-Pythonic
if len(my_list) >= 6:
print(my_list[5])
else:
print("That index does not exist")
---------------------------------
That index does not exist
---------------------------------
==========================================
my_list = [1, 2, 3, 4, 5, 6]
# Pythonic
try:
print(my_list[5])
except IndexError:
print("That index does not exist")
---------------------------------
6
---------------------------------
==========================================
my_list = [1, 2, 3, 4, 5]
# Pythonic
try:
print(my_list[5])
except IndexError:
print("That index does not exist")
---------------------------------
That index does not exist
---------------------------------
==========================================
# Example from the Python Docs
import os
my_file = "/tmp/test.txt"
# Race Condition
if os.access(my_file, os.R_OK):
with open(my_file) as f:
print(f.read())
else:
print("File can not be accessed")
---------------------------------
File can not be accessed
---------------------------------
==========================================
# Example from the Python Docs
import os
my_file = "/tmp/test.txt"
# No Race-Condition
try:
f = open(my_file)
except IOError as e:
print("File can not be accessed")
else:
with f:
print(f.read())
---------------------------------
File can not be accessed
---------------------------------