Python 全攻略:Chapter 13 - Miscellaneous Information (159-162)

▌ 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.
1個讚