▌ Type checking function
- type(object): returns class type of the argument passed as parameter.
- isinstance(object, class): returns a Boolean value indication if the object belongs to or inherits from the class.
主要作用是檢查一個物件Object是否是某個類別Class的實例
- issubclass(classA, classB): returns a Boolean value indication if classA is a subclass of classB.
用來檢查一個類別ClassA是否為另一個類別ClassB的子類別
- type(), isinstance() and issubclass() functions check an object’s type and inheritance relations, we usually use them for debugging purposes.
type()
print(type("Goodbye"))
print(type("Hello")==type("Goodbye"))
print(type("Hello")==type(5))
-----------------------------------------------------------------
<class 'str'>
True
False
isinstance(), issubclass()
class C:
pass
class B(C): # B inheits C
pass
class A(B): # A inheits B
pass
c = C()
b = B()
a = A()
print(isinstance(a, A))
print(isinstance(a, B)) # A 如果inherits B,它就會 inherits 它所有的 methods 跟 attributes
print(isinstance(c, A))
print(issubclass(A, A)) # 跟離散數學有關,因為自己是自己的子集合
print(issubclass(A, B))
print(issubclass(C, A))
-----------------------------------------------------------------
True
True
False
True
True
False
▌ Duck Typing
- Duck Typing is a way of programming in which an object passed into a function or method supports all method signatures and attributes expected of that object at run time. The object’s type itself is not important. Rather, the object should support all methods/attributes called on it. For this reason, duck typing is sometimes seen as “a way of thinking rather than a type system”.
- Duck test: “If it walks like a duck and it quacks like a duck, then it must be a duck”
sorted()
- The sorted function is using the principle of duck typing
- This is the Duck typing style design
print(sorted(['foo', 'bar', 'fox']))
print(sorted({'foo', 'bar', 'fox'}))
print(sorted({'key1':'foo','key2':'bar', 'key3':'fox'}))
print(sorted('foobarfox'))
print(sorted(99644))
-----------------------------------------------------------------
['bar', 'foo', 'fox']
['bar', 'foo', 'fox']
['key1', 'key2', 'key3']
['a', 'b', 'f', 'f', 'o', 'o', 'o', 'r', 'x']
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-d45358455d06> in <cell line: 0>()
5 print(sorted({'key1':'foo','key2':'bar', 'key3':'fox'}))
6 print(sorted('foobarfox'))
----> 7 print(sorted(99644))
TypeError: 'int' object is not iterable
def calculate(x, y, z):
return (x + y) * z
print(calculate([1, 3], ['book'], 5))
---------------------------------------------------------------------------
[1, 3, 'book', 1, 3, 'book', 1, 3, 'book', 1, 3, 'book', 1, 3, 'book']
▌ Review OOP programing
- OOP: Object-oriented programming(OOP) is a method of structuring a program by bundling related properties and bevaiors into individual objects.
- OOP Style in Python: OOP design emphasizes information hiding; this is known as “encapsulation”. All attributes of an object should be as private as possible.
- __Dunder method__(): Dunder or Magic Methods are the methods having two prefixes and suffix underscores in the method name. We’ve learned such as __init__(), __init__(), __setitem__(), __getitem__(), __str__()
- object.__getitem__(self, key)
- object.__setitem__(self, key, value): Python built-in method which called to implement assignment to self[key]. These methods used only in indexed attributes like arrays, dictionaries, lists.
- __functionName(): Add a double underscore at the front and the attribute or method would become private.
- Super(): Returns a proxy object that allows us to access methods of the base class.
▌ TypeList
- In other languages like Java or C++, we can only create lists of a specific type at a time. However, we don’t have that built-in in Python; therefore, we have to build it on our own.
確保加進 TypeList 裡的元素都是同一個 type
寫法一:沒有 inherit from list
class TypedList:
def __init__(self, example_element, initial_list):
self.type = type(example_element)
if not isinstance(initial_list, list): # initial_list至少要是list
raise TypeError("Second argument of TypedList must be a list.")
for element in initial_list:
self.__check(element)
# self.elements = initial_list # copy by reference
self.elements = initial_list[:] # copy by 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']
寫法二:讓 TypeList 直接 inherits list (Python built-in class)
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 TypedList must be a list.")
for element in initial_list:
self.__check(element)
super().__init__(initial_list) # super()作為父類別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)
# 可以刪除 __str__, __add__ 原因在於Python list class 本身已 dunder method str, add
x = TypedList('Hello', ['Some', 'original', 'stuff'])
print(x)
---------------------------------------------------------------------------
['Some', 'original', 'stuff']
TypeList內的元素必須為同一個屬性
x = TypedList('Hello', ['Some', 'original', 10])
print(x)
---------------------------------------------------------------------------
TypeError: Attempted to add an element of incorrect type to a TypedList.
y = TypedList('', [''] * 5)
y[3] = "15"
y[4] = 'hello'
print(y)
---------------------------------------------------------------------------
['', '', '', '15', 'hello']
y = TypedList('', [''] * 5)
y[3] = 5
y[4] = 'hello'
print(y)
---------------------------------------------------------------------------
TypeError: Attempted to add an element of incorrect type to a TypedList.
▌ Decimal, Binary, and Hexadecimal
- Decimal (十進制): Human beings use decimal number systems.
- Binary (二進制): Computers use binary number systems. (due to the nature of electricity)
- Hexadecimal (十六進制): Computer hardware(including CPUs and memories) uses a hexadecimal number system.
y = TypedList('', [''] * 5)
y[3] = 5
y[4] = 'hello'
print(y)
---------------------------------------------------------------------------
TypeError: Attempted to add an element of incorrect type to a TypedList.