Python 全攻略第十三章 MISC Information

Python 全攻略第十三章 MISC Information

Duck Typing

  • Type checking functions (usually use them for debugging purposes)
    • type(object) → returns class type
    • isinstance(object, class) → returns a Boolean value
    • issubclass(classA, classB) → returns a Boolean value (notice that a class is a subclass of itself)
  • Duck typing
    • refers to Python’s way of determining whether an object is a required type for an operation
    • As long as the object has the functionality we need, we don’t necessarily need to know its data type
# type(object)
print(type("goodbye"))
print(type('hello') == type("goodbye"))
print(type('hello') == type(5))
<class 'str'>
True
False
# is instance(obj, class)
class C:
    pass

class B(C):
    pass

class A(B):
    pass

a = A()
b = B()
c = C()

print(isinstance(a, A))
print(isinstance(a, B))
print(isinstance(a, C))
print("_" * 50)
print(isinstance(c, A)) # False

print("_" * 50)
print(issubclass(A, A))
print(issubclass(A, B))
print(issubclass(A, C))
print("_" * 50)
print(issubclass(C, A)) # False
print(issubclass(C, B))  # False
print(issubclass(C, C))
True
True
True
__________________________________________________
False
__________________________________________________
True
True
True
__________________________________________________
False
False
True
# the sorted function is using the principle of Duck Typing
l = ['foo', 'bar', 'fox']
t = ('foo', 'bar', 'fox')
s = {'foo', 'bar', 'fox'}
d = {'key1': 'foo', 'key2': 'bar', 'key3': 'fox'}

print(sorted(l), sorted(t), sorted(s), sorted(d), sep='\n')

print("_" * 50)
try:
    print(sorted(99644))
except:
    print("Error happened while using sorted function")
['bar', 'foo', 'fox']
['bar', 'foo', 'fox']
['bar', 'foo', 'fox']
['key1', 'key2', 'key3']
__________________________________________________
Error happened while using sorted function
# We can design a function that uses the principle of Duck Typing as well
def calculate(x, y ,z):
    return (x + y) * z

print(calculate(3, 2, 1))
print(calculate('foo', 'bar', 3))
print(calculate([1, 3], [4, 2], 5))
5
foobarfoobarfoobar
[1, 3, 4, 2, 1, 3, 4, 2, 1, 3, 4, 2, 1, 3, 4, 2, 1, 3, 4, 2]

TypedList

  • It is a data type that all elements inside the list must be the same type
  • We don’t have that built-in in Python, so we need to build it on our own
  • One-type list makes the list stable and eases the error tracking
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 TypedList must be a list")
        for element in initial_list:
            self.__check(element)
        self.elements = initial_list[:] # copy by value

    def __check(self, element):
        if type(element) != self.type:
            raise TypeError("incorrect type element detected")

    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)

y = TypedList(' ',[' ']*5)
y[3] = '15'
y[4] = 'hello'
print(y)
print(x + y)
['Some', 'original', 'Stuff']
[' ', ' ', ' ', '15', 'hello']
8
class TypedList(list): # inherit list (Modified_01)
    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)
        # self.elements = initial_list[:]  # (Modified_02)
        super().__init__(initial_list) # New Code

    def __check(self, element):
        if type(element) != self.type:
            raise TypeError("incorrect type element detected")

    def __setitem__(self, i, element):
        self.__check(element)
        # self.elements[i] = element  # Modified_03
        super().__setitem__(i, element) # New Code

    def __getItem__(self, i):
        # return self.elements[i]  # Modified_04
        return super().__getitem__(i) # New Code

x = TypedList('Hello', ['Some', 'original', 'Stuff'])
print(x)

y = TypedList(' ', [' ']*5)
print(x+y)
['Some', 'original', 'Stuff']
['Some', 'original', 'Stuff', ' ', ' ', ' ', ' ', ' ']

Different Number Systems

  • Decimal {0, 1, 2, 3 ,4 ,5, 6, 7, 8, 9}
  • Binary {0, 1}, and Hexadecimal {0, 1, 2, 3 ,4 ,5, 6, 7, 8, 9, A, B, C, D, E, F}
  • When working with raw data (binary data - such as images or music), Python byte comes in handy.
  • hex(integer number) =>return a string => start with the \color{tomato}{prefix\ 0x}
  • bin(integer number) =>return a string => start with the \color{tomato}{prefix\ 0b}
print(hex(25))
print(hex(255))

print("_" * 50)
print(bin(255))
print(bin(4789))
0x19
0xff
__________________________________________________
0b11111111
0b1001010110101

Encoding and UTF-8

  • ASCII (American Standard Code for Information Interchange)
    • It is a character encoding standard for electronic communication
    • Most modern character-encoding schemes are based on ASCII
    • It uses 1 byte (8 bits) to do encoding, but actually ony 7 bits are used (128 characters)
    • includes upper and lower English letters, 0 ~ 9 and some symbols (such as !@#$%)
  • Unicode (a superset of ASCII) maintained by Unicode Consortium
    • 144,697 charactors, covering 159 modern and historic scripts
    • as well as symbols, emoji and non-visual control and formatting codes
    • UTF-8 is the most commonly used encoding to map binary digits to Unicode
    • UTF-8 is a \color{tomato}{variable\ length} encoding with a minimum of 8 bits per character
    • UTF-8 can encode Unicode characters in range of 1 to 4 bytes (32bits)
    • \color{tomato}{Chris\ 兄補充學習資源: }
      • Dr. Fred 有關編碼注意事項的教學 => YouTube 影片
      • Sky 兄先前分享有關於此主題的 => 筆記
  • In \color{tomato}{Python\ 3} - a string is an immutable sequence of \color{tomato}{Unicode} characters
  • string.encode(encoding method, utf-8, utf-16 or something else) => returns the bytes
  • byte.decode(decoding method) => returns the string
emoji_string = '👍🕷️㊙️🆘🚀💯'
print(emoji_string)

unicode_string = '中'
utf_byte = unicode_string.encode() # default encoding 為 utf-8
print(utf_byte)  # b'\xe4\xb8\xad' (use three bytes)
# e4 => 1110 0100 (1110 xxxx Mutiple bytes, two more bytes follow)
# b8 => 1011 1000 (10xx xxxx continuation)
# ad => 1010 1101 (10xx xxxx continuation)

print("_" * 50)
result_string = utf_byte.decode() # default decoding 為 utf-8
print(result_string)
👍🕷️㊙️🆘🚀💯
b'\xe4\xb8\xad'
__________________________________________________
中
1個讚