print(type("goodbye")) #<class 'str'>
print(type("goodbye") == type("hello")) #True
print(type("goodbye") == type(3)) #False
class C:
pass
class B(C):
pass
class A(B):
pass
a = A()
b = B()
c = C()
print(isinstance(a, A)) #True
print(isinstance(a, B)) #True
print(isinstance(a, C)) #True
print(isinstance(c, A)) #False
print(issubclass(A, A)) #True
print(issubclass(A, B)) #True
print(issubclass(A, C)) #True
print(issubclass(C, A)) #False
If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
# The sorted function is using the principle of duck typing
# This is a Duck Typing style design
print(sorted(['foo','bar','fox'])) #['bar', 'foo', 'fox']
print(sorted({'foo','bar','fox'})) #['bar', 'foo', 'fox']
print(sorted({'key1':'foo', 'key2':'bar', 'key3':'fox'})) #['key1', 'key2', 'key3']
print(sorted('foobarfox')) #['a', 'b', 'f', 'f', 'o', 'o', 'o', 'r', 'x']
print(sorted(99644)) #TypeError: 'int' object is not iterable
try:
print(sorted(99644))
except:
print("Error happened while sorted")
def calculate(x, y,z):
return (x + y) * z
print(calculate(3, 2, 2)) #10
print(calculate('foo', 'bar', 2)) #foobarfoobar
print(calculate([1, 3], [4, 2], 3)) #[1, 3, 4, 2, 1, 3, 4, 2, 1, 3, 4, 2]
try:
print(calculate([1, 3], 3, 5))
except:
print('we got error')
The advantage of a one-type list includes tracking errors and making the list stable. If we add something that shouldn’t be in the list, we can quickly figure it out at the beginning of our development.
class TypedList:
def __init__(self, example_element, initial_list):
self.type = type(example_element)
if not isinstance(initial_list, list):
raise TypeError("Second argument of TypedLisst must be a list.")
for element in initial_list:
self.__check(element)
self.elements = initial_list[:] #copy be value
def __check(self, element):
if type(element) != self.type:
raise TypeError(
"Attempted to add an element of incorrect type to a TypedList.")
def __setitem__(self, i, element):
self.__check(element)
self.elements[i] = element
def __getitem__(self, i):
return self.elements[i]
def __str__(self):
return str(self.elements)
def __add__(self, anotherList):
return len(self.elements) + len (anotherList.elements)
x = TypedList('Hello', ['some', 'original', 'stuff'])
print(x) #['some', 'original', 'stuff']
y = TypedList('', [''] * 5)
print(y) #['', '', '', '', '']
print(x + y) #8
class TypedList(list):
def __init__(self, example_element, initial_list):
self.type = type(example_element)
if not isinstance(initial_list, list):
raise TypeError("Second argument of TypedLisst must be a list.")
for element in initial_list:
self.__check(element)
super().__init__(initial_list)
def __check(self, element):
if type(element) != self.type:
raise TypeError(
"Attempted to add an element of incorrect type to a TypedList.")
def __setitem__(self, i, element):
self.__check(element)
super().__setitem__(i, element)
def __getitem__(self, i):
return super().__getitem__(i)
x = TypedList('Hello', ['Some', 'original', 'stuff'])
print(x) #['Some', 'original', 'stuff']
y = TypedList('', [''] * 5)
print(y) #['', '', '', '', '']
print(x + y) #['Some', 'original', 'stuff', '', '', '', '', '']