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\ 兄補充學習資源: }
- 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'
__________________________________________________
中