###### Tags: `Python` `基礎` # Python ## 基本數據類型 ### 整數 | 前綴 | 例子 | 進制 | |:--------:|:----------:|:----:| | 無 | a = 10 | 10 | | 0b or 0B | b = ob1010 | 2 | | 0o or 0O | c = 0o12 | 8 | | 0x or 0X | d = 0xa | 16 | ```python= >>> a = 10 >>> type(a) <class 'int'> >>> b = 0b1010 >>> b 10 >>> c = 0o12 >>> c 10 >>> d = 0xa >>> d 10 ``` ### 浮點數 ```python= a = 1.2 b = .4 c = 1.2e-4 # 1.2乘於10的-4次方 ``` ```python= >>> a = 1.2 >>> type(a) <class 'float'> >>> b = .4 >>> b 0.4 >>> c = 1.2e-4 >>> c 0.00012 ``` #### 浮點數運算特例 ##### // 取無條件捨去整數除法 ```python= >>> 2/4 0.5 >>> 2//4 0 ``` ##### 浮點數運算 結果還是浮點數 ```python= >>> 0.2 * 5 1.0 >>> 0.2 // 0.4 0.0 ``` ### 字串 可使用'''包起字串,中間就可以使用"與' ```python= >>> a = '''test "1" '2' ''' >>> a 'test "1" \'2\' ' >>> print(a) test "1" '2' ``` 用\\包引號可以顯示引號 ```python= >>> a = "這是"家"" File "<stdin>", line 1 a = "這是"家"" ^ SyntaxError: invalid syntax >>> a = "這是\"家\"" >>> a '這是"家"' ``` #### 字串操作 ```python= >>> a= "test" >>> a[-2] 's' >>> len(a) 4 >>> a = "1" >>> b = "2" >>> a + b '12' >>> a * b Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't multiply sequence by non-int of type 'str' >>> a * 10 '1111111111' ``` #### 字串格式化 ##### 推薦用 f"" ```python= name = 'Python' age = 27 new_str = "我是" + name + "," + "今年" + str(age) + "歲了" print(new_str) new_str_1 = "我是%s,今年%d歲了" % (name, age) print(new_str_1) new_str_2 = "我是{},今年{}歲了".format(name, age) #順序對應 print(new_str_2) new_str_2b = "我是{name},今年{age}歲了".format( #key value 對應 name = 'aaa', age = 'bbb' ) print(new_str_2b) new_str_3 = f"我是{name},今年{age}歲了" print(new_str_3) ``` ##### 小數點精確度:.2f :代表顯示幾位數 ```python= print(f"{age:.2f}") # 27.00 ``` ##### 顯示正號:+ ```python= print(f"{age:+.2f}") # +27.00 ``` ##### 對齊 ```python= num1 = 12 num2 = -23 num3 = 100 # 限制長度10預設靠右對齊 print(f"數字1是 {num1:10.2f}") # 數字1是 12.00 print(f"數字2是 {num2:10.2f}") # 數字2是 -23.00 print(f"數字3是 {num3:10.2f}") # 數字3是 100.00 # 靠左對齊 print(f"數字1是 {num1:<10.2f}") # 數字1是 12.00 print(f"數字2是 {num2:<10.2f}") # 數字2是 -23.00 print(f"數字3是 {num3:<10.2f}") # 數字3是 100.00 # 置中對齊 print(f"數字1是 {num1:^10.2f}") # 數字1是 12.00 print(f"數字2是 {num2:^10.2f}") # 數字2是 -23.00 print(f"數字3是 {num3:^10.2f}") # 數字3是 100.00 ``` ### 布林值 ```python= >>> a = True >>> type(a) <class 'bool'> ``` ### 空值 ```python= >>> a = None >>> a >>> type(a) <class 'NoneType'> ``` ## 列表 ```python= a = [1,2,3] b = [1, 'abc', 2.0, ['a', 'b', 'c']] print(a) print(b) print(a[0],a[1]) #預設會以空格間隔並換行 print(a[0],a[1], sep='-',end='**') #修改間隔與結尾 c = b[1:3] #從第幾個 print(c, type(c)) #['abc', 2.0] <class 'list'> ``` ### 列表基本操作 ```python= list1 = [9, 1, -4, 3, 7, 11, 3] print('list1的長度=',len(list1)) print('list1裡的最大值=',max(list1)) print('list1裡的最小值=',min(list1)) print('list1裡 3 這個元素一共出現{}次'.format(list1.count(3))) ``` ```python= list2 = ['a', 'c', 'd'] list2.append('e') print('list2=', list2) # list2= ['a', 'c', 'd', 'e'] list2.insert(1,'b') print('list2=', list2) # list2= ['a', 'b', 'c', 'd', 'e']list2.remove('b') list2.remove('b') print('list2=', list2) # list2= ['a', 'c', 'd', 'e'] list2[0] = '1' print('list2=', list2) # list2= ['1', 'c', 'd', 'e'] ``` ```python= a = '123' a[0] = 'a' # TypeError: 'str' object does not support item assignment ``` ### 列表翻轉 ```python= list3 = [1, 2, 3] list3.reverse() print('list3=', list3) # list3= [3, 2, 1] ``` ### 列表排序 ```python= list3 = [1, 2, 3] list3.reverse() print('list3=', list3) # list3= [3, 2, 1] list4 = [9, 1, -4, 3, 7, 11, 3] list4.sort() print('list4=', list4) # list4= [-4, 1, 3, 3, 7, 9, 11] list4.sort(reverse=True) print('list4=', list4) # list4= [11, 9, 7, 3, 3, 1, -4] ``` ## 元組(Tuple) ```python= a = (1, 2, 3) b = 1, print(a, type(a)) # (1, 2, 3) <class 'tuple'> print(b, type(b)) # (1,) <class 'tuple'> a = (1, 2, 3) b = [1, 2, 3] print(a[1]) # 2 print(a[1:3]) # (2, 3) print(a[1:]) # (2, 3) ``` ### 元組基本操作 元組內的值不可更動 ```python= tuple1 = (9, 1, -4, 3, 7, 11, 3) print('tuple1的長度=',len(tuple1)) # tuple1的長度= 7 print('tuple1裡的最大值=',max(tuple1)) # tuple1裡的最大值= 11 print('tuple1裡的最小值=',min(tuple1)) # tuple1裡的最小值= -4 print('tuple1裡 3 這個元素一共出現{}次'.format(tuple1.count(3))) # tuple1裡 3 這個元素一共出現2次 ``` ```python= tuple2 = ('a', 'c', 'd') tuple2[1] = 2 # 元組不可賦值 翻轉、排序都不行 ``` ```python= print(tuple1.index(9)) # 0 ``` #### 元組進階操作 ##### 切片 ```python= my_tuple = ('python', 3, 7, 3 ) print(my_tuple[0:2]) # ('python', 3) ``` ##### 序列解包 ```python= my_tuple = ('python', 3, 7, 3 ) name, _, y, z = my_tuple # 略過用下底線 print(name, y, z) # python 7 3 ``` ```python= my_tuple = ('python', 3, 7, 3 ) name, *_, = my_tuple # 之後都略過 print(name) # python ``` ```python= my_tuple = ('python', 3, 7, 3 ) name, *version, = my_tuple # 之後的組成列表 print(name, version) # python [3, 7, 3] ``` ## 列表 & 元組 比較 | 列表 | 元組 | |:------------:|:--------------------------:| | 固定一塊內存 | 兩塊內存 一塊數據 一塊擴展 | | 比元組靈活 | 建立&讀取比陣列 快 | ## 字典 不可改變的數據類型 ```python= a = { 1: 'a', 2: 'b', '3': 'c' } print(type(a)) # <class 'dict'> l1 = [1, 2, 3] b = { l1: 1 } # TypeError: unhashable type: 'list' t1 = (1, 2, 3) c = { t1: l1 } print(c) # {(1, 2, 3): [1, 2, 3]} d = dict() print(d) # {} e = dict(a=1, b=2, c='a') print(e) # {'a': 1, 'b': 2, 'c': 'a'} print(e['a']) # 1 e['c'] = 3 e['d'] = 123 print(e) {'a': 1, 'b': 2, 'c': 3, 'd': 123} ``` ### 字典基本操作 ```python= d = { 'Name' : 'Jack', 'Age' : 9, 'Grade' : 5 } print(d['Name']) # Jack print(d.get('name')) # none ``` #### 取得有哪些 key ```python= print(d.keys()) # dict_keys(['Name', 'Age', 'Grade']) ``` #### 取得有哪些 value ```python= print(d.values()) # dict_values(['Jack', 9, 5]) ``` #### 以元組方式取得結果 ```python= print(d.items()) # dict_items([('Name', 'Jack'), ('Age', 9), ('Grade', 5)]) ``` #### pop ```python= c= d.pop('Name') print(c) # Jack print(d) # {'Age': 9, 'Grade': 5} ``` #### clear ```python= d.clear() print(d) # {} ``` #### update ```python= c = { 1: 1, 2: 2 } d = { 5: 5, 6: 6 } c.update(d) # c |= d print(c) # {1: 1, 2: 2, 5: 5, 6: 6} e = {**c, **d} # e = c | d print(e) # {1: 1, 2: 2, 5: 5, 6: 6} ``` ### 字典進階操作 #### dict().setdefault 算重複次數 ```python= word_list = ['is', 'who', 'when', 'it', 'is', 'who', 'is'] result = dict() # for word in word_list: # if word not in result: # result[word] = 1 # else: # result[word] += 1 # # print(result) for word in word_list: result.setdefault(word, 0) result[word] += 1 print(result) # {'is': 3, 'who': 2, 'when': 1, 'it': 1} ``` #### 初始化字典 defaultdict(類型) ```python= word_list = ['is', 'who', 'when', 'it', 'is', 'who', 'is'] from collections import defaultdict result = defaultdict(int) for word in word_list: result[word] += 1 print(result) # defaultdict(<class 'int'>, {'is': 3, 'who': 2, 'when': 1, 'it': 1}) ``` ## 集合 ```python= a = { 'a', 'b', 'c' } b = { 'a': 1, 'b': 2, 'c': 3 } print(type(a)) # <class 'set'> t = 'c' in a print(t) # True l = [1, 2, 3, 2, 4, 5, 2] s1 = set(l) print(s1) # {1, 2, 3, 4, 5} print(list(s1)) # [1, 2, 3, 4, 5] a = '1234512' s1 = set(a) print(s1) # {'4', '3', '5', '1', '2'} ``` ### 集合基本操作 ```python= s = { 1, 2, 3, 4 } s.add(5) print(s) # {1, 2, 3, 4, 5} s.remove(5) print(s) # {1, 2, 3, 4} ``` #### 集合交集 ```python= s1 = { 1, 2, 3, 4 } s2 = { 3, 4, 5, 6 } print(s1 & s2) # {3, 4} ``` #### 集合全集 ```python= s1 = { 1, 2, 3, 4 } s2 = { 3, 4, 5, 6 } print(s1 | s2) # {1, 2, 3, 4, 5, 6} ``` #### 集合差集 ```python= s1 = { 1, 2, 3, 4 } s2 = { 3, 4, 5, 6 } print(s1 ^ s2) # {1, 2, 5, 6} ``` #### 集合相減 有存在的條件就去除 ```python= s1 = { 1, 2, 3, 4 } s2 = { 3, 4, 5, 6 } print(s1 - s2) # {1, 2} print(s2 - s1) # {5, 6} ``` ## 條件 ### if ```python= a = int(input('請輸入一個數字:')) # 12 print(a,type(a)) # 12 <class 'int'> if a > 0: print('這是一個大於0的數字') # 這是一個大於0的數字 ``` ### if ... else ```python= a = int(input('請輸入一個數字:')) # 0 print(a,type(a)) # 0 <class 'int'> if a > 0: print('這是一個大於0的數字') else: print('這是一個小於或等於0的數字') # 這是一個小於或等於0的數字 ``` ### if ... elif ... else ```python= a = int(input('請輸入一個數字:')) # 0 print(a,type(a)) # 0 <class 'int'> if a > 0: print('這是一個大於0的數字') elif a == 0: print('這是0') # 這是0 else: print('這是一個小於0的數字') ``` ## 循環 ### while ```python= a = 10 while a > 0: print(a) # 10 9 8 7 6 5 4 3 2 1 a -= 1 print('結束') # 結束 ``` ### for ```python= a = '12345' b = [1, 2, 3, 4] c = ('a','b','c','d') d = { 1: 'a', 2: 'b', 3: 'c' } for item in d: print(item) # in a: 1 2 3 4 5 # in b: 1 2 3 4 # in c: a b c d # in d: 1 2 3 ``` ```python= d = { 1: 'a', 2: 'b', 3: 'c' } for item in d.items(): print(item) # (1, 'a') # (2, 'b') # (3, 'c') for a, b in d.items(): print('{}={}'.format(a,b)) # 1=a # 2=b # 3=c ``` ```python= e = {1, 2, 3, 4, 5} for item in e: print(item) # in d: 1 2 3 5 9 ``` #### range(start,stop,step) ```python= for item in range(1, 20, 4): print(item) # 1 5 9 13 17 ``` #### enumerate(list) ```python= items = ['a','b','c','d'] for index,item in enumerate(items): print(index,item) # 0 a # 1 b # 2 c # 3 d ``` ## break & continue ### break ```python= for i in range(10): print(i) # 0 1 if i % 2 != 0: break ``` ### continue ```python= for i in range(10): if i % 2 == 0: continue print(i) # 1 3 5 7 9 ``` #### 練習 ```python= import random answer = random.randint(0, 100) guess = int(input('請猜0~100間的數字: ')) max = 100 min = 0 while guess != answer: if guess == answer: break elif guess > answer: max = guess guess = int(input(f'請猜{min}~{max}間的數字: ')) else: min = guess guess = int(input(f'請猜{min}~{max}間的數字: ')) print('答對了,答案是:', guess) ``` ## 函數 ```python= def demo(): print('hello world') demo() # Hello World def demo1(a, b): print(a, b) demo1(a=[1,2,3],b={1:1,2:2}) # [1, 2, 3] {1: 1, 2: 2} def sum(a,b): return a + b print(sum([1,2],[3,4])) # [1, 2, 3, 4] ``` ### 練習 e.x.最大值 ```python= def my_max(a): if not a: return None max_value = a[0] for item in a: if item > max_value: max_value = item return max_value a = [1, 4, 5, 2, 3, 8, 10] print(my_max(a)) ``` ## scope ```python= x = 1 x += 1 print(x) # 2 def demo(): x = 10 a = 11 print(x) # 10 print(a) # NameError: name 'a' is not defined demo() print(x) # 2 ``` ```python= y = [1, 2, 3] print(y) # [1, 2, 3] def demo1(a): a = a + [4] print(a) # [1, 2, 3, 4] demo1(a=y) print(y) # [1, 2, 3] ``` ### 用append等函數會改變全域變數 ```python= y = [1, 2, 3] print(y) # [1, 2, 3] def demo1(a): a.append(4) print(a) # [1, 2, 3, 4] demo1(a=y) print(y) # [1, 2, 3, 4] ``` ### 函數更改全域變數的方式 ```python= z = 1 print(z) # 1 def demo2(a): global z # global z = z + a print(z) # 11 demo2(10) print(z) # 11 ``` ## 可變參數 可變參數必須放最後面 ### *args ```python= def add(*args): # *args接受多個參數成一個元組 print(args) # (1, 2 ,3) result = 0 for item in args: result += item return result print(add(1, 2, 3)) # 6 ``` ### **kwargs ```python= def add(**kwargs): #**kwargs接受多個參數成一個字典 print(kwargs) # {'a': 1, 'b': 2, 'c': 3} return (kwargs.get('a') + kwargs.get('b')) * kwargs.get('c') print(add(a=1, b=2, c=3)) # 9 ``` ### 參數默認值 有默認值的參數要放在最後 ```python= def test(a,b=False): if b: return a else: return a * a print(test(a=2,b=True)) # 2 ``` ## 遞歸 ```python= # n! = 1*2*3.........(n-1)*n # n * (n-1) * (n-2)...... 2*1! # def test(n): # result = 1 # for item in range(1,n+1): # result *= item # return result def test(n): if n==1: return n return n * test(n-1) print(test(4)) # 24 ``` ## 推導式 用更少的語法創建新列表 ### 列表推導式 * [運算 迴圈 條件式] 原寫法: ```python= def square(x): return x * x list=[] for i in range(1 , 11): list.append(square(i)) print(list) ``` 推導式寫法: ```python= newSquare = [i*i for i in range(1 , 11)] print(newSquare) ``` e.x: ```python= grades = [100,98,84,77,66,45] passed_grades = [i for i in grades if i>=60] print(passed_grades) ``` ### 字典推導式 * {key:expression for (key,value) in interable} e.x: ```python= cities_in_F = {'LA': 120, 'New York': 65, 'Chicago': 50, "Miami": 150 } cities_in_C = { key: (value - 32) * 5 / 9 for (key, value) in cities_in_F.items() } print(cities_in_F) print(cities_in_C) ``` e.x: ```python= weather = {'台北': '大晴天', '台中': '大晴天', '宜蘭': '下雨', '台東': '下雨' } sunny_weather = {key: value for (key, value) in weather.items() if value == '大晴天'} print(sunny_weather) ``` e.x: ```python= cities_in_F = {'LA': 120, 'New York': 65, 'Chicago': 50, "Miami": 150 } def check_temp(value): if value >= 70: return '熱' elif value >= 40: return '溫暖' else: return '冷' description_cities = { key: check_temp(value) for (key,value) in cities_in_F.items()} print(description_cities) ``` ## zip函式 三個以上的物件就無法轉成列表跟字典 ```python= usernames = ["Raiden", "Rodes", "ZZ"] passwords = ("123", "321", "666") users = zip(usernames,passwords) print(users) # <zip object at 0x000001A07749C700> ``` ```python= for i in users: print(i) # ('Raiden', '123') # ('Rodes', '321') # ('ZZ', '666') ``` ```python= print(list(users)) # [('Raiden', '123'), ('Rodes', '321'), ('ZZ', '666')] ``` ```python= print(dict(users)) # {'Raiden': '123', 'Rodes': '321', 'ZZ': '666'} ``` ```python= usernames = ["Raiden", "Rodes", "ZZ"] passwords = ("123", "321", "666") date = ["2000-11-13","1989-11-13","2020-11-13"] users = zip(usernames,passwords,date) print(users) for i in users: print(i) print(list(users)) print(dict(users)) # <zip object at 0x0000017E510FC900> # ('Raiden', '123', '2000-11-13') # ('Rodes', '321', '1989-11-13') # ('ZZ', '666', '2020-11-13') # [] # {} ``` ## class & object ### class ```python= # __init__() method 方法 # attribute 屬性 # method 方法 class People: def __init__(self, name, age): self.name = name self.age = age def sayhi(self): print("Hi my name is {}, and I'm {}".format( self.name, self.age )) someone = People(name='Jack', age=20) print(someone.name) # Jack print(someone.age) # 20 someone.sayhi() # Hi my name is Jack, and I'm 20 ``` ### 受保護屬性 & 私有屬性 _:只是標記受保護,可修改 __: 只有class內可修改 ```python= class People: def __init__(self, name, age): self.name = name self.age = age self._protect_var = 10 self.__private_var = 10 def sayhi(self): print("Hi my name is {}, and I'm {}".format( self.name, self.age )) def get_var(self): print(self.__private_var) def set_var(self,var): self.__private_var = var someone = People(name='Jack', age=20) someone.sayhi() # Hi my name is Jack, and I'm 20 someone.age = 30 someone.sayhi() # Hi my name is Jack, and I'm 30 someone._protect_var = 30 print(someone._protect_var) # 30 print(someone.__private_var) # AttributeError: 'People' object has no attribute '__private_var' someone.get_var() # 10 someone.set_var(30) someone.get_var() # 30 ``` ```python= someone._protect_var = 30 print(someone._People__private_var) # 10 someone._People__private_var = 30 someone.get_var() # 30 ``` ### property ```python= class People: def __init__(self, name, age): self.__name = name self.__age = age @property def name(self): # 格式規範 return self.__name.upper() @property def age(self): return self.__age @name.setter def name(self, name): # 合法性檢查 self.__name = name def set_age(self, age): self.__age = age someone = People(name='Jack', age=20) print(someone.name) # JACK print(someone.age) # 20 someone.name ='Test' # TEST print(someone.name) ``` ## 繼承和多態 ```python= class Animal: def eat(self): print('Animal is eating') class Bird(Animal): def sing(self): print('Bird is singing...') def eat(self): print('Bird is eating...') class Cat(Animal): pass class Dog(Animal): def eat(self): print('Dog is eating') a = Animal() b = Bird() c = Cat() d = Dog() def demo_eat(a): a.eat() for item in [a, b, c, d]: demo_eat(item) # Animal is eating # Bird is eating... # Animal is eating # Dog is eating ``` ## 類屬性 & 實例屬性 ```python= class Student: count = 0 # 類屬性 def __init__(self, name): self.name = name # 實例屬性 print(Student.count) # 0 ``` ```python= class Student: count = 0 # 類屬性 def __init__(self, name): self.name = name # 實例屬性 s1 = Student(name='A') print(s1.name) # A ``` ```python= class Student: count = 0 def __init__(self, name): Student.count +=1 self.name = name s1 = Student(name='A') s2 = Student(name='B') s3 = Student(name='C') print(Student.count) # 3 ``` ## 類方法 & 實例方法 & 靜態方法 ```python= class People: def __init__(self, name, age): self.name = name self.age = age def sayhi(self): # 實例方法 print(f"Hi, my name is {self.name}, and I'm {self.age}") @classmethod # 類方法 def test1(cls): print('這是一個類方法') @staticmethod # 靜態方法 def test2(): print('這是一個靜態方法') p1 = People(name='Jack',age=20) p1.sayhi() # Hi, my name is Jack, and I'm 20 p1.test1() # 這是一個類方法 People.test1() # 這是一個類方法 p1.test2() # 這是一個靜態方法 People.test2() # 這是一個靜態方法 ``` ## Package ### 新增 Package New -> Python Package ### 建立引用檔案 math.py ```python= def my_sum(*args): result = 0 for item in args: result += item return result def my_max(*args): print('最大值') def my_min(*args): print('最小值') class People: def __index__(self, name, age): self.name = name self.age = age ``` ### 引入檔案 test.py ```python= from ch8.demo.math import my_sum print(my_sum(1, 2, 3, 4)) # 10 ``` ```python= import ch8.demo.math as myMath print(myMath.my_sum(1, 2, 3, 4)) # 10 ``` ### sys import sys 在終端機執行程式,路徑才不會報錯 ## 異常處理 ### try ... except ```python= a = [10, 4, 3, 7, 11, 6, 0, 9, 22] try: b = [item for item in a if 100% item == 0] except: print('發生錯誤') print('完成') # 發生錯誤 # 完成 ``` except 可接錯誤類型(只捕捉該類異常) ```python= a = [10, 4, 3, 7, 11, 6, 0, 9, 22] try: b = [item for item in a if 100% item == 0] except ZeroDivisionError: print('O不能為除數') print('完成') # O不能為除數 # 完成 ``` 其餘異常 ```python= a = [10, 4, 3, 7, 11, 6, 1, 9, 22,'10'] try: b = [item for item in a if 100% item == 0] except ZeroDivisionError: print('O不能為除數') except TypeError: print('數據類型錯誤') except Exception: print('其它類型異常') print('完成') ``` finally無視異常照樣執行 ```python= a = [10, 4, 3, 7, 11, 6, 1, 9, 22,'10'] try: b = [item for item in a if 100% item == 0] except ZeroDivisionError: print('O不能為除數') except TypeError: print('數據類型錯誤') except Exception: print('其它類型異常') finally: print('清理工作') ``` ### 自定義異常 raise ```python= class MyException(Exception): pass raise MyException("這是用戶定義異常") # Traceback (most recent call last): # File "C:\Users\fixer2\PycharmProjects\Python3-OOP\ch11\user_defined_exception.py", line 4, in <module> # raise MyException("這是用戶定義異常") # __main__.MyException: 這是用戶定義異常 ``` ```python= class MyException(Exception): pass try: raise MyException("這是用戶定義異常") except MyException as e: print(e) # 這是用戶定義異常 ``` ```python= class MyException(Exception): pass def my_interaction(): raise MyException('這是用戶定義的異常') try: my_interaction() except MyException as error: print(error) else: print('Executing the else clause.') try: my_interaction() except MyException as error: print(error) else: try: with open('file.log') as file: read_data = file.read() except FileNotFoundError as fnf_error: print(fnf_error) finally: print('清理工作') # 這是用戶定義的異常 # 這是用戶定義的異常 # 清理工作 ``` ## 測試 ### pdb ```python= import pdb pdb.set_trace() numbers = [1, 2, 3, 4, 10, -4, -7, 0] def all_even(num_list): even_numbers = [] for number in num_list: if number%2 == 0: even_numbers.extend(number) return even_numbers all_even(numbers) ``` ```python -> numbers = [1, 2, 3, 4, 10, -4, -7, 0] (Pdb) ``` | | s | n | p | | ---- |:------------:|:------------:|:--------------------:| | 用法 | 一行一行執行 | 直接執行函數 | 接函數名稱可印出內容 | ### Pychram Debug ### doc test ```python def func_demo(a,b): """ doc test demo >>> func_demo(1, 2) 3 >>> func_demo('a', 'b') 'ab' >>> func_demo([1, 2], [3, 4]) [1, 2, 3, 4] >>> func_demo(1, '2') Traceback (most recent call last): TypeError: unsupported operand type(s) for +: 'int' and 'str' """ return a + b if __name__ == "__main__": import doctest doctest.testmod() ``` ### 單元測試 ```python= import unittest from demo.math import add class TestAdd(unittest.TestCase): def test_add(self): self.assertEqual(add(1, 2), 3) if __name__ == '__main__': unittest.main() ``` ```python Ran 1 test in 0.010s OK ``` ```python= import unittest from demo.math import add class TestAdd(unittest.TestCase): def test_add(self): self.assertEqual(add(1, 2), 3) def test_add_2(self): self.assertEqual(add(10, 20), 300) if __name__ == '__main__': unittest.main() ``` ```python Ran 2 tests in 0.021s FAILED (failures=1) 300 != 30 Expected :30 Actual :300 <Click to see difference> Traceback (most recent call last): File "C:\Users\fixer2\PycharmProjects\Python3-OOP\ch12\test_math.py", line 9, in test_add_2 self.assertEqual(add(10, 20), 300) AssertionError: 30 != 300 ``` ## 日誌紀錄 logging ```python= """ debug(), info(), warning(), error(), critical() 越右邊級別越高 """ import logging logging.basicConfig(level='DEBUG') # 設定顯示哪個級別的log logging.debug('this is debug') logging.info('this is info') logging.warning('this is warning') logging.error('this is error') logging.critical('this is critical') ``` ```python DEBUG:root:this is debug INFO:root:this is info WARNING:root:this is warning ERROR:root:this is error CRITICAL:root:this is critical ``` ### filename & filemode filename: 將log輸出成檔案 filemode: 預設為a增加寫入,w為覆蓋寫入 ```python= logging.basicConfig(level='DEBUG', filename='test.log', filemode='w') ``` ### logging format 設置 ```python= import logging format = '%(levelname)s-%(name)s-%(message)s' # 格式設置 logging.basicConfig(level='INFO', format=format) def main(): logging.debug('this is debug') logging.info('this is info') logging.warning('this is warning') logging.error('this is error') logging.critical('this is critical') if __name__ == "__main__": main() ``` ```python INFO-root-this is info WARNING-root-this is warning ERROR-root-this is error CRITICAL-root-this is critical ``` ### logging 對象設置 ```python= import logging logger = logging.getLogger(name='demo') logger.setLevel(logging.DEBUG) # Create handlers c_handler = logging.StreamHandler() f_handler = logging.FileHandler('file.log') c_handler.setLevel(logging.ERROR) f_handler.setLevel(logging.INFO) # Create formatters and add it to handlers c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s') f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') c_handler.setFormatter(c_format) f_handler.setFormatter(f_format) # Add handlers to the logger logger.addHandler(c_handler) logger.addHandler(f_handler) def main(): logger.debug('this is debug') logger.info('this is info') logger.warning('this is warning') logger.error('this is error') logger.critical('this is critical') if __name__ == "__main__": main() ``` ```python demo - ERROR - this is error demo - CRITICAL - this is critical ``` ### 使用配置文件設定 logger (log.conf)) ## time模組 ```python= import time print(time.ctime(0)) print(time.time()) local_time = time.localtime() print("格式化時間:",time.strftime("%Y-%m-%d %H:%M:%S", local_time)) # Thu Jan 1 08:00:00 1970 # 1709954820.1143064 # 格式化時間: 2024-03-09 11:27:00 ``` 字串轉時間的物件 ```python= import time time_string = "2024-03-09 11:30:30" time_object = time.strptime(time_string,"%Y-%m-%d %H:%M:%S") print(time_object) # time.struct_time(tm_year=2024, tm_mon=3, tm_mday=9, tm_hour=11, tm_min=30, tm_sec=30, tm_wday=5, tm_yday=69, tm_isdst=-1) ```