1.1. Polymorphism¶
1.1.1. Switch¶
Switch moves business logic to the execution place:
watney = 'Astronaut'
if watney == 'Astronaut':
print('Hello')
elif watney == 'Cosmonaut':
print('Привет!')
elif watney == 'Taikonaut':
print('你好')
else:
print('Default Value')
# Hello
def say_hello(key=None):
return {
'Astronaut': 'Hello',
'Cosmonaut': 'Привет!',
'Taikonaut': '你好',
}.get(key, 'Default Value')
watney = 'Astronaut'
ivanovic = 'Cosmonaut'
twardowski = 'Sorcerer'
say_hello(watney)
# Hello
say_hello(ivanovic)
# Привет!
say_hello(twardowski):
# 'Default Value'
1.1.2. Polymorphism in a Function¶
Polymorphism on Function:
class Sorcerer:
pass
class Astronaut:
def say_hello(self):
return 'Hello'
class Cosmonaut:
def say_hello(self):
return 'Привет!'
def say_hello(spaceman):
if hasattr(spaceman, 'say_hello')
return spaceman.say_hello()
else:
return 'Default Value'
watney = Astronaut()
ivanovic = Cosmonaut()
twardowski = Sorcerer()
say_hello(watney)
# Hello
say_hello(ivanovic)
# Привет!
say_hello(twardowski)
# 'Default Value'
1.1.3. Polymorphism on a Class¶
Polymorphism on Classes:
class Astronaut:
def __init__(self, name):
self.name = name
def say_hello(self):
return 'Hello'
class Cosmonaut:
def __init__(self, name):
self.name = name
def say_hello(self):
return 'Witaj!'
crew = [
Astronaut('Mark Watney'),
Cosmonaut('Иван Иванович'),
Astronaut('Matt Kowalski'),
Cosmonaut('Pan Twardowski'),
]
for member in crew:
print(member.say_hello())
# Hello
# Witaj!
# Hello
# Witaj!
1.1.4. Factory¶
DATA = [
('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
(5.8, 2.7, 5.1, 1.9, 'virginica'),
(5.1, 3.5, 1.4, 0.2, 'setosa'),
(5.7, 2.8, 4.1, 1.3, 'versicolor'),
(6.3, 2.9, 5.6, 1.8, 'virginica'),
(6.4, 3.2, 4.5, 1.5, 'versicolor'),
(4.7, 3.2, 1.3, 0.2, 'setosa'),
]
class Iris:
def __init__(self, sepal_length, sepal_width, petal_length, petal_width):
self.sepal_length = sepal_length
self.sepal_width = sepal_width
self.petal_length = petal_length
self.petal_width = petal_width
def __repr__(self):
name = self.__class__.__name__
values = tuple(self.__dict__.values())
return f'\n {name}{values}'
class Setosa(Iris):
pass
class Virginica(Iris):
pass
class Versicolor(Iris):
pass
def factory(species: str):
if species == 'setosa':
return Setosa
if species == 'virginica':
return Virginica
if species == 'versicolor':
return Versicolor
result = []
for *features, species in DATA[1:]:
iris = factory(species)
i = iris(*features)
result.append(i)
print(result)
# [Virginica(5.8, 2.7, 5.1, 1.9),
# Setosa(5.1, 3.5, 1.4, 0.2),
# Versicolor(5.7, 2.8, 4.1, 1.3),
# Virginica(6.3, 2.9, 5.6, 1.8),
# Versicolor(6.4, 3.2, 4.5, 1.5),
# Setosa(4.7, 3.2, 1.3, 0.2)]
from dataclasses import dataclass
DATA = [
('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
(5.8, 2.7, 5.1, 1.9, 'virginica'),
(5.1, 3.5, 1.4, 0.2, 'setosa'),
(5.7, 2.8, 4.1, 1.3, 'versicolor'),
(6.3, 2.9, 5.6, 1.8, 'virginica'),
(6.4, 3.2, 4.5, 1.5, 'versicolor'),
(4.7, 3.2, 1.3, 0.2, 'setosa'),
]
@dataclass
class Iris:
sepal_length: float
sepal_width: float
petal_length: float
petal_width: float
class Setosa(Iris):
pass
class Virginica(Iris):
pass
class Versicolor(Iris):
pass
def factory(species: str):
species = species.capitalize()
classes = globals()
return classes[species]
result = [
factory(species)(*features)
for *features, species in DATA[1:]
]
print(result)
# [Virginica(sepal_length=5.8, sepal_width=2.7, petal_length=5.1, petal_width=1.9),
# Setosa(sepal_length=5.1, sepal_width=3.5, petal_length=1.4, petal_width=0.2),
# Versicolor(sepal_length=5.7, sepal_width=2.8, petal_length=4.1, petal_width=1.3),
# Virginica(sepal_length=6.3, sepal_width=2.9, petal_length=5.6, petal_width=1.8),
# Versicolor(sepal_length=6.4, sepal_width=3.2, petal_length=4.5, petal_width=1.5),
# Setosa(sepal_length=4.7, sepal_width=3.2, petal_length=1.3, petal_width=0.2)]