# Python Basic fundamental ###### tags: `python` --- > >* **本文內容為“Tibame快速闖關Python語法世界,程式實作不頭痛”為主,版權為issac所有,本文僅做筆記用途,非商業用途** > >* **本篇圖片部分出自“Tibame快速闖關Python語法世界,程式實作不頭痛”課程內容講義** > --- # :memo: Introduction ## 1. Python特色 - 可讀性高 - 跨平台 - 豐富第三方套件 - 直譯式語言 - 腳本語言 - 膠水語言 ## 2. python生態系 ![](https://i.imgur.com/Zhaif6Q.png) # :memo: Principle of Operation ## 1. Python keyword ![](https://i.imgur.com/33Q4RvF.png) ## 2. Python Identifier Identifier命名可區分不同名稱: - 變數(Variable) - 函數(Function) - 類別(Class) Identifier命名規則 - 由 A-Z, a-z, 0-9, _所組成 - 第一字元不可為0-9 - 大小寫有區別 - 不要使用keyword命名 Identifier命名偵測是否有效 ```python= print("abc".isidentifier()) #True print("99a".isidentifier()) #Flase ``` Identifier命名格式 - snake_case(ex: my_cat_name, my_cat_age) - lowerCamelCase(ex: myCatName, myCatAge) - UpperCamelCase(ex: MyCatName, MyCatAge) - CAPITZLIZE(ex:PI,HOSTNAME) ## 3. Python Literals **1. Literals為Python內建給予變數與常數的原始資料** String literals : "halo" , '12345' Int literals : 0,1,2,-1,-2 Long literals : 89675L Float literals : 3.14 Complex literals : 12j Boolean literals : True or False Special literals : None Unicode literals : u"hello" List literals : [], [5,6,7] Tuple literals : (), (9,),(8,9,0) Dict literals : {}, {'x':1} Set literals : {8,9,10} **2. Numeric Literals (進位)** EX:數字10,11 Decimal (十進位): 10, 11 Binary (二進位): 0b1010, 0B1011 Octal (八進位): 0o12, 0O13 Hexadecimal (十六進位): 0xa, 0XB **3. 逃脫字元** ![](https://i.imgur.com/lk8QPgw.png) ## 4. Python Variable **定義:用來儲存數值而被保留之記憶體** ![](https://i.imgur.com/1KBibBb.png =312x146) **Object (物件)** 變數從memory找到對應之物件提取其內容 ![](https://i.imgur.com/eZAiNGD.png) 其中包含id、type、value - identity(id):回傳此物件在memory中的位置 - type:物件之型別 - value:物件內之值 ![](https://i.imgur.com/7PLros4.png) **動態類型** Python為動態類型語言,可自動偵測變數之型別 C/Java為靜態類型語言,需要先指定變數型別 **命名規則** - 只能透過英文大小寫(A-Z,a-z), 數字(0-9), 底線(_) - 不能用數字作為開頭 - 區分大小寫 - 底線(_)開頭 ## 5. Python Operator - Arithmetic Operator: ==+, -, *, /, %, **, //== :::info :bulb:Hint: %表示餘數,//表示商 ::: - Comparison Operator: ==\==, !=, >, <, >=, <\=== - Assignment Operator ![](https://i.imgur.com/R0fFy4y.png =500x) - Logical Operator: ==and, or, not== - Membership Operator: ==in, not in== ![](https://i.imgur.com/tdukjtC.png =200x) - Identity Operator: ==is, is not== ![](https://i.imgur.com/DOsXSMH.png =400x) - Bitwise Operator: ==&, |, ^, <<, >>== &: AND(Both True=>True, Other=>False) |: OR(Both False=>False, Other=>True) ^: XOR(True False=>True, Other=>False) <<, >>:Shift Bit ![](https://i.imgur.com/amihri7.png =400x) ![](https://i.imgur.com/eg7wS2p.png =300x) - 運算優先順序 ![](https://i.imgur.com/VsqjhzO.png) # :memo: Data Types ## 1. Numeric Type (int, float, complex) | int | float |complex | | --------|----------|----------| | 5 | 0.0 | 5+3j | | 22 | 22.5 | 5.j | | -3 | -3.89 | -3.89j | | 0b1010 | -3. | .3j | | -0b1011 | 18.3e+9 | 18.3e+9j | | 0x220 | -18.3e+9 | 18.3e-9j | ## 2. Boolean Type (bool) Boolen only **True** or **False** ![](https://i.imgur.com/DzDj7RJ.png =300x) ## 3. Sequence Type (str, list, tuple) ### **string** Imutable #### 1. 常見string函數 ```python= s = "Surprise" s2 = "MotherFucker" print(s[0]) #S print(s[4:]) #rise print(s[0::2]) #Srrs print(s+s2) #SurpriseMotherFucker print(s*2) #SurpriseSurprise print(len(s)) #8 print(min(s)) #S print(max(s)) #u print("S" not in s) #False print("M" in s2) #True ``` #### 2. string分割函數 ```python= s3 = "I Love U" print(s3.split()) #['I', 'Love', 'U'] mails = ["abcn@yahoo.com.tw", "wooddn@hotmail.com", "kkzaa@gmail.com"] print(mails[0].split("@")[1].split(".")[0]) #先用@分割,再用.分割 #"yahoo" ``` #### 3. string去首尾函數 ```python= str1 = "乂JoJo乂乂" str2 = " 乂JoJo乂乂 " print(str1.strip("乂")) #"JoJo" print(str2.strip()) #"乂JoJo乂乂" a = "\tabc" b = "abc\n\r" print(a.strip()) #"abc" print(b.strip()) #"abc" ``` #### 5. string 單引號&雙引號應用 ```python= print("I'm Joseph") #雙引號內單引號不用跳脫 print('I\'m Joseph') #單引號內有單引號要跳脫 print('I said "Why"') #單引號內雙引號不用跳脫 print("I said \"Why\"") #雙引號內有雙引號要跳脫 ``` ### **list** 定義1:list為**有序**且**可修改**之元素集合(mutable) 定義2:允許多個重複元素 定義3:允許list內元素為不同type Example: name_list = ['Joseph', 'Emma', 'Julia', 'Julian'] | list | Joseph | Emma | Julia | Julian | | ------------------|--------|------|-------|--------| | Index from head | 0 | 1 | 2 | 3 | | Index from tail | -4 | -3 | -2 | -1 | #### 1. 常見字串函數 ```python= name_list = ["Joseph", "Emma", "Julia", "Julian"] name_list.append("Judy") #['Joseph', 'Emma', 'Julia', 'Julian', 'Judy'] name_list.remove("Judy") #['Joseph', 'Emma', 'Julia', 'Julian'] name_list2 = name_list.copy() #['Joseph', 'Emma', 'Julia', 'Julian'] name_list.index("Emma") #1 (位置1) name_list.extend(name_list2) #['Joseph', 'Emma', 'Julia', 'Julian', 'Joseph', 'Emma', 'Julia', 'Julian'] name_list.count("Julia") #2 (出現兩次) name_list2.insert(2, "Judy") #['Joseph', 'Emma', 'Judy', 'Julia', 'Julian'] del name_list2[2] #['Joseph', 'Emma', 'Julia', 'Julian'] name_list2.pop() #['Joseph', 'Emma', 'Julia'] (最尾巴的去除) print(name_list2.pop()) #Julia, name_list2 = ['Joseph', 'Emma'] name_list.reverse() #['Julian', 'Julia', 'Emma', 'Joseph', 'Julian', 'Julia', 'Emma', 'Joseph'] name_list.sort() #['Emma', 'Emma', 'Joseph', 'Joseph', 'Julia', 'Julia', 'Julian', 'Julian'] #replace不改寫list,此用法會回傳新的字串 list1 = ["Holy", "Shit"] list1[1].replace("S", "s") #shit print(list1) #["Holy", "Shit"] name_list.clear() #[] ``` #### 2.list合併函數 ```python= list1 = ["S", "H", "I", "T"] print("".join(list1)) #SHIT print('-'.join(list1)) #S-H-I-T ``` #### 3.list值合併函數 ```python= #list中值加總 list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9] print(sum(list1)) #45 #list與list之間合併 list1 = [1, 2, 3] list2 = [4, 5, 6] list3 = list1 + list2 #[1, 2, 3, 4, 5, 6] #list與list之間合併成dict list_a = ["Joseph", "Emma", "Julia"] list_b = [1, 2, 3] dic1 = dict(zip(list_a, list_b)) #{'Joseph': 1, 'Emma': 2, 'Julia': 3} ``` ### **tuple** 定義1:tuple為**有序**且**不可修改**之元素集合(immutable) 定義2:“**不**”允許多個重複元素 定義3:允許tuple內元素為不同type Example: person1 = ("Joseph", 180, 75) | tuple | Joseph | 180 | 75 | | ------------------|--------|-----|----| | Index from head | 0 | 1 | 2 | | Index from tail | -3 | -2 | -1 | #### 1. 常見字串函數 ```python= person1 = ("Joseph", 180, 75) person1 += ("Taipei", ) #利用逗號來使程市判別()內為tuple而非運算用 print(person1) #("Joseph", 180, 75, "Taipei") print(person1[0]) #Joseph print(person1[:2]) #Joseph 180 print(len(person1)) #4 #person1[0]與person1[0:1]不同,一個是單一文字,一個是tuple型態 print(person1[0]) #"Joseph" print(person1[0:1]) #("Joseph",) print(person1[0:1] + person1[2:]) #("Joseph", 75, 'Taipei') # tuple刪除? 不用,因為本身是短暫用 # 要用也可,可以繞彎達成 ``` #### 2.list合併函數 ```python= t1 = ("S", "H", "I", "T") print("".join(t1)) #"SHIT" print('-'.join(t1)) #"S-H-I-T" ``` #### 3.sort()函數 ```python= #Sorted()輸出為list t1 = ("S", "H", "I", "T") print(sorted(t1)) #['H', 'I', 'S', 'T'] ``` ## 4. Hash Type (dict, set) ### **dict** 定義1:dictionary為無序且一堆**key** & **value**之元素集合 定義2:key不可重複 #### 1. 常見字串函數 ```python= person = {"Name":"Joseph", "Height":180, "Handsome":True} #取值: print(name) print("Name: ", person["Name"]) #Name: Joseph #新增語法 person["Weight"] = 75 print(person) #{'Name': 'Joseph', 'Height': 180, 'Handsome': True, 'Weight': 75} #更新內容 person["Weight"] = 72 print(person) #{'Name': 'Joseph', 'Height': 180, 'Handsome': True, 'Weight': 72} #數值取出來做運算並且更新 person["Height"] = person["Height"] +3 print(person) #{'Name': 'Joseph', 'Height': 183, 'Handsome': True, 'Weight': 72} #刪除 del person["Weight"] print(person) #{'Name': 'Joseph', 'Height': 177, 'Handsome': True} #len print(len(person)) #3 ``` #### 2. iter()函數 ```python= lis1 = {"A":11, "B":22, "C":33, "D":44, "E":55} print(id(lis1)) # printing type print ("The list is of type:" + str(type(lis1))) # converting list using iter() lis1 = iter(lis1) print(id(lis1)) # printing type print ("The iterator is of type:" + str(type(lis1))) # using next() to print iterator values print (next(lis1)) print (next(lis1)) print (next(lis1)) print (next(lis1)) print (next(lis1)) ``` ### **set** 定義1:set為無序且無索引(index)之元素集合 定義2:不可重複元素 #### 1. 常見字串函數 ```python= name_set = {"周", "林", "黃", "周"} print(name_set) #{'黃', '周', '林'} # 會改變set內部指令:add, discard name_set.add("王") #{'黃', '周', '林', '王'} name_set.discard("王") #{'黃', '周', '林'} #聯集:兩個的聯集 name_set = name_set.union({"何", "周"}) print(name_set) #{'周', '何', '黃', '林'} ``` ## 5. String formatting ```python= a = 100 b = 8.9 c = "hello" d = 1+2j print("{} {} {}".format(a, b, c) #"100 8.9 hello" print("{0} {1} {2}".format(a, b, c)) #"100 8.9 hello" print("{2} {1} {0}".format(a, b, c)) #"hello 8.9 100" print("{0}, {0.real}, {0.imag}".format(d)) #(1+2j), 1.0, 2.0 print("x, y = {x}, {y}".format(x="3", y="4")) #x, y = 3, 4 #dict type coord = {"w": "6", "h": "8"} print("w, h = {w}, {h}".format(**coord)) #w, h = 6, 8 #tuple type coord2 = (8, 9) print("X: {0[0]}; Y: {0[1]}".format(coord2)) #X: 8; Y: 9 #調整位數 #hint: d=integer f=float s=string print('{0:10d} {1:10f} {2:10s}'.format(a, b, c)) #設10個位數 print('{0:>10d} {1:>10f} {2:>10s}'.format(a, b, c)) #靠右 print('{0:<10d} {1:<10f} {2:<10s}'.format(a, b, c)) #靠左 print('{0:^10d} {1:^10f} {2:^10s}'.format(a, b, c)) #靠中間 #' 100 8.900000 hello ' #' 100 8.900000 hello' #'100 8.900000 hello ' #' 100 8.900000 hello ' #進位 #hint: int:十進位 bin:二進位 oct:八進位 hex:十六進位 print('int: {0:d}; bin: {0:b}; oct: {0:o}; hex: {0:x}'.format(99)) #'int: 99; bin: 1100011; oct: 143; hex: 63' print('int: {0:#d}; bin: {0:#b}; oct: {0:#o}; hex: {0:#x}'.format(99)) #'int: 99; bin: 0b1100011; oct: 0o143; hex: 0x63' print(':,'.format(1234567890)) #'1,234,567,890' #小數點 e = 33 f = 19 print('percentage = {:.2%}'.format(b/a)) #小數點兩位 #'percentage = 57.58%' #時間格式 import datetime date1 = datetime.datetime(2020, 1, 1, 12, 34, 56) print('{:%Y-%m-%d %H:%M:%S}'.format(date1)) #'2020-1-1 12:34:56' ``` [f-string](https://www.twblogs.net/a/5b822eca2b717737e032da80) Better and faster than format ```python= a = 100 b = 8.9 c = 'hello' d = 1+2j print(f"{a} {b} {c}") #"100 8.9 hello" #dict type coord = {"w": "6", "h": "8"} print(f"w, h = {coord['w']}, {coord['h']}") #w, h = 6, 8 #tuple type coord2 = (8, 9) print(f"X: {coord2[0]}; Y: {coord2[1]}") #X: 8; Y: 9 #調整位數 #hint: d=integer f=float s=string print(f"{a:10d} {b:10f} {c:10s}") #設10個位數 print(f"{a:>10d} {b:>10f} {c:>10s}") #靠右 print(f"{a:<10d} {b:<10f} {c:<10s}") #靠左 print(f"{a:^10d} {b:^10f} {c:^10s}") #靠中間 #' 100 8.900000 hello ' #' 100 8.900000 hello' #'100 8.900000 hello ' #' 100 8.900000 hello ' #進位 #hint: int:十進位 bin:二進位 oct:八進位 hex:十六進位 print(f"int: {99:d}; bin: {99:b}; oct: {99:o}; hex: {99:x}") #'int: 99; bin: 1100011; oct: 143; hex: 63' print(f"int: {99:#d}; bin: {99:#b}; oct: {99:#o}; hex: {99:#x}") #'int: 99; bin: 0b1100011; oct: 0o143; hex: 0x63' print(f"{1234567890:,}") #'1,234,567,890' #小數點 e = 33 f = 19 print(f"percentage = {f/e:.2%}") #小數點兩位 #'percentage = 57.58%' #時間格式 from datetime import datetime as dt date1 = dt(2020, 1, 1, 12, 34, 56) print(f"{date1:%Y-%m-%d %H:%M:%S}") #'2020-1-1 12:34:56' ``` # :memo: Flow ## 1. 條件式 if/else/elif 定義1:True/False條件敘述,若條件式為True則執行縮排內程式區塊 定義2:執行順序為if==>elif==>elif...==>else ```python= import random answer = random.randint(1, 5) guess = int(input("Guess: ")) if guess > answer: print('{} is bigger than answer'.format(guess)) elif guess < answer: print('{} is smaller than answer'.format(guess)) else: print('bingo! is ', answer) ``` ### 巢狀式流程控制 ```python= import random answer = random.randint(1, 5) guess = int(input("Guess: ")) if guess >= 1 and guess <=5: if guess > answer: print('{} is bigger than answer'.format(guess)) elif guess < answer: print('{} is smaller than answer'.format(guess)) else: print('bingo! is ', answer) else: print("Guess is not in range") ``` ## 2. 迴圈 while/for ### **while** 定義:在條件式為True時,可重複執行某一段程式區塊 ```python= answer = 3 guess = 0 while guess != answer: guess = int(input('please make guess during 1~6.: ')) if guess > answer: print('bigger than answer') continue #直接跳去while那一行 elif guess < answer: print('smaller than answer') else: print('bingo') break #中斷此while迴圈 print('Still in while loop.\n') ``` ### **for** 定義:用來迭代序列化資料,ex: list, tuple, dictionary ```python= for i in 'Joseph': print(f'{i}', end='') #f'{}'方便做帶入 #Joseph ``` ```python= Name_list = ['Joseph', 'Emma', 'Julian'] for i in Name_list: print(f'Name: {i}') # Name: Joseph # Name: Emma # Name: Julian for i in range(len(Name_list)): print(i) print(my_list[i]) # 0 Joseph # 1 Emma # 2 Julian for index, i in enumerate(Name_list): print(index,i) # 0 Joseph # 1 Emma # 2 Julian pos = [i for i,x in enumerate(Name_list) if x == "Joseph"] #[0] ``` ```python= for i in range(5): print(i, end='') #01234 print('') for i in range(1, 5): print(i , end='') #1234 print('\n', end='') for i in range(1, 10, 2): print(i, end='') #13579 print('\n', end='') for i in range(5, 0, -1): print(i, end='') #54321 ``` ```python= my_dict = {'Joseph':50, 'Emma':80, 'Judy':20} for i in my_dict: print(i, my_dict[i]) # Joseph 50 # Emma 80 # Judy 20 for i in my_dict.values(): print(i) # 50 # 80 # 20 ``` 巢狀迴圈 ```python= n=5 for i in range(n): for j in range(i): print ('* ', end="") print('') for i in range(n,0,-1): for j in range(i): print('* ', end="") print('') # * # * * # * * * # * * * * # * * * * * # * * * * # * * * # * * # * ``` # :memo: Function ## 自訂函數 定義:A-Z, a-z, *_*,0-9,第一個不能為數字 定義:可設計成輸入參數(parameters)與回傳值(return) ```python= #可以設預設值 def score(name, grade, class1='Sunny'): print(name + "'s math grade is: %s" %grade) print(r'class is', class1) score('Joseph', 98) # Joseph's math grade is: 98 # class is Sunny #可以將參數變“動參數”增加多個參數輸入 def namelist(*names): for name in names: print(name) return names #--> tuple namelist('Joseph', 'Emma', 'Julian') # Joseph # Emma # Julian #可以將參數變“動參數”接收字典 def feature(**keyvalue): print('FEATURE:', keyvalue) return keyvalue #-->dict feature(Name='Joseph', Height=180, Handsome=True) # FEATURE: {'Name': 'Joseph', 'Height': 180, 'Handsome': True} #回傳值功能 def Returnfuc(): a = 'apple' b = 'banana' c = 'cat' return a, b, c print(Returnfuc()) # ('apple', 'banana', 'cat') type==>tuple ``` ## 內建函數 ![](https://i.imgur.com/Zd9ZCZR.png) ### 常用函數 ```python= abs(-1) #1 round(3.4) #3 pow(3,2) #9 divmod(3,2) #(2,1) str(10) #10 bin(10) #0b1010 oct(10) #0o12 hex(10) #0xa list1 = [1,2,3,4,5] sum(list1) #15 min(list1) #1 max(list1) #5 txt1='100' a = int(txt1) print(f'a = {a}, {type(a)}') #a = 100, <class 'int'> txt2='100.87' b = float(txt2) print(f'b = {b}, {type(b)}') # b= 100.87, <class 'float'> ``` ## 全域變數 定義:任何區塊的程式碼可存取之變數 ```python= def function2(): global a #將變數a變為全域變數,函數跳出時變數a才不會消失 a += 1 #變數a變成1000 print(a) a = 999 function2() #1000 ``` ## 區域變數 定義:只能在程式區塊可存取之變數 ```python= def sumofbitch(a, b): c = a + b #變數a, b, c只存取於此程式區塊 print(a) return c print(sumofbitch(1,2)) #1 先運算sumofbitch(1,2) #3 後print ``` ## lambda函數 定義:使用一行就能完成函數定義 ```python= #before def double(a): return a*2 double(5) #10 #after x = lambda a:a*2 x(5) #10 ``` 結合filter()可選則符合條件之元素 ```python= #filter(function, iterable) list1 = [1,2,3,4,5,6,7,8,9] odd_list = list(filter(lambda x:(x%2==1),list1)) print(odd_list) # [1, 3, 5, 7, 9] ``` 結合map()可選所有元素一起轉換 ```python= #map(function, iterable) list1 = [1,2,3,4,5,6,7,8,9] odd_list = list(map(lambda x:x**2,list1)) print(odd_list) # [1, 4, 9, 16, 25, 36, 49, 64, 81] ``` 結合reduce()可選多個元素做合併 ```python= #reduce(function, iterable) from functools import reduce list1 = [1,2,3,4,5] odd_list = reduce(lambda x, y:x+y,list1) print(odd_list) #((((1+2)+3)+4)+5) # 15 ``` ## 遞迴函數 定義:自己呼叫自己 ```python= def factorial(n): if n==0 or n==1: return 1 else: return n*factorial(n-1) print(factorial(4)) #24 ``` ### 動態規劃 因為避免遞迴浪費太多記憶體,可先將部分函數存起來,要用到可直接取得 以費氏定理來舉例: |F(0)|F(1)|F(2)|F(3)|F(4)|F(5)|F(6)|F(7)|F(8)| |:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:| |0 |1 |1 |2 |3 |5 |8 |13 |21 | ```python= #before def F(n): if n==0 or n==1: return n else: return F(n-1)+F(n-2) print(F(8)) #21 #after def fibonacciVal(n): memo = [None]*(n+1) memo[0], memo[1] = 0, 1 for i in range(2, n+1): memo[i] = memo[i-1]+memo[i-2] return memo[n] #memo[2] = 1, memo[3] = 2,... print(fibonacciVal(8)) #21 ``` # :memo: Class ## 物件導向語言(Object-oritented Programming,OOP) 定義1:所有資料皆是物件 定義2:提高軟體重複使用性、方便擴充性、方便維護性 ## 基本語法 定義:第一個字母要大寫 ```python= class Banks(): title = 'Taiwan Bank' def word(self): print("Hello!!") bank1 = Banks() print(bank1.title) bank1.word() #有self需要有() #Taiwan Bank #Hello!! ``` ### 1.\_\_init\_\_函數 class被創建時,\_\_init\_\_會被直接執行 ```python= class Banks(): def __init__(self, uname): self.name = uname #public==>他人可以查詢得到 self.balance = 0 self.bankname = "Taipei Bank" def save_money(self, money): self.balance += money print("save ", money, "Finish") def withdraw_money(self, money): self.balance -= money print("draw ", money, "Finish") def get_balance(self): print(self.name, "Rest: ", self.balance) bank1 = Banks('Joseph') bank1.save_money(300) #save 300 Finish bank1.get_balance() #Joseph Rest: 300 bank1.withdraw_money(300) #draw 300 Finish bank1.get_balance() #Joseph Rest: 0 ``` ### 2.實體屬性(Instance Attribute) 定義:各自物件實體屬性各自獨立,修改某一物件屬性時,不會影響另一物件之屬性 ```python= class Banks(): def __init__(self, uname): self.name = uname #public==>他人可以查詢得到 self.balance = 0 self.bankname = "Taipei Bank" def save_money(self, money): self.balance += money print("save ", money, "Finish") def withdraw_money(self, money): self.balance -= money print("draw ", money, "Finish") def get_balance(self): print(self.name, "Rest: ", self.balance) bank1 = Banks('Joseph') bank2 = Banks('Emma') bank1.save_money(300) #save 300 Finish bank1.get_balance() #Joseph Rest: 300 bank2.save_money(1000) #save 1000 Finish bank2.get_balance() #Emma Rest: 300 ``` ### 3.類別屬性(Class Attribute) 定義:各自物件共享類別屬性,類別屬性修改,各自物件之屬性一起修改 ```python= class Banks(): location = "Taiwan" def __init__(self, uname): self.name = uname #public==>他人可以查詢得到 self.balance = 0 self.bankname = "Taipei Bank" def save_money(self, money): self.balance += money print("save ", money, "Finish") def withdraw_money(self, money): self.balance -= money print("draw ", money, "Finish") def get_balance(self): print(self.name, "Rest: ", self.balance) bank1 = Banks('Joseph') bank2 = Banks('Emma') print("original location:", bank1.location) #Taiwan print("original location:", bank2.location) #Taiwan Banks.location = "America" print("New location:", bank1.location) #America print("New location:", bank2.location) #America ``` ### 4.屬性(Property) 定義:可控制類別中的屬性,並且可以用方法(method)來設定規則 ```python= #範例需求:Bank名字可以修改,但是要為字串 class Banks(): location = "Taiwan" def __init__(self, uname): self.name = uname #此處還是為public,後方則為private self.__balance = 0 self.__bankname = "Taipei Bank" @property def name(self): # print('get name') return self.__name @name.setter def name(self, new_name): # print('set name') if type(new_name) == str: self.__name = new_name else: raise TypeError('name need str.') def save_money(self, money): self.__balance += money print("save ", money, "Finish") def withdraw_money(self, money): self.__balance -= money print("draw ", money, "Finish") def get_balance(self): print(self.__name, "Rest: ", self.__balance) bank1 = Banks('JOJO') print(bank1.name) #JOJO bank1.name = 'Emma' print(bank1.name) #名字修改成Emma ``` ## 封裝(encapsulation) 將類別內attribute/method私有化,class外部無法使用內部資訊 使用方法:在attrubute/method前面加上"__" ```python= #函數私有化==>__XXX class Banks(): def __init__(self, uname): self.__name = uname #private==>私有化內容 self.__balance = 0 self.__bankname = "Taipei Bank" def save_money(self, money): self.__balance += money print("save ", money, "Finish") def withdraw_money(self, money): self.__balance -= money print("draw ", money, "Finish") def get_balance(self): print(self.__name, "Rest: ", self.__balance) bank1 = Banks('Joseph') bank1.save_money(300) #save 300 Finish bank1.__name = 'JoJo' #經過封裝後修改無效化 bank1.get_balance() #Joseph Rest: 300 bank1.withdraw_money(300) #draw 300 Finish bank1.get_balance() #Joseph Rest: 0 ``` ## 繼承(inheritance) attribute/method可以被繼承 繼承者:子類別(subclass) 被繼承者:父類別(superclass) ```python= class Banks(): def __init__(self, uname, money): self.name = uname #public==>他人可以查詢得到 self.balance = money self.bankname = "Taipei Bank" def get_balance(self): print(self.name, "has: ", self.balance) return self.balance class Daan_Banks(Banks): #Daan_Banks == subclass pass #Banks == superclass bank1 = Banks('Joseph', 1000) bank1.get_balance() #Joseph has: 1000 ``` ### 多重繼承 ```python= class Grandfather(): def action1(self): print("I'm grandfather.") class Father(Grandfather): def action2(self): print("I'm father.") super().__init__() class Uncle(Grandfather): def action3(self): print("I'm uncle.") super().__init__() class Son(Father, Uncle): def action4(self): print("I'm son.") super().__init__() son = Son() son.action1() #I'm grandfather. son.action2() #I'm father. son.action3() #I'm uncle. son.action4() #I'm son. ``` ## 多型(polymorphism) 預設狀態子類別會繼承父類別,但若子類別method與父類別相同,會覆寫父類別method ```python= class Animals(): def __init__(self, animal_name): self.name = animal_name def which(self): return 'Name:'+ self.name.title() def action(self): return 'sleeping' #有繼承 class Dogs(Animals): def __init__(self, dog_name): super().__init__(dog_name.title()) def which(self): return 'Name:'+ self.name.title() def action(self): return 'eating' #無繼承 class Cats(): def __init__(self, cat_name): self.name = 'Name:' + cat_name.title() def which(self): return self.name def action(self): return 'playing' def do(obj): print(obj.which(), '', obj.action()) bear = Animals('JOJO') do(bear) #Name:Jojo sleeping dog = Dogs('DOGGY') do(dog) #Name:Doggy eating cat = Cats('Catty') do(cat) #Name:Catty playing ``` # :memo: try/except 使用時機:當執行程式時,可能會產生預期之外之行為,可使用try/except語法解決 ```python= #使用前 def divison(a, b): return a / b print(divison(3,0)) #ZeroDivisionError: division by zero #使用後 def divison(a, b): try: return a / b # None except (ZeroDivisionError) as e: print('[Error]: Divisor can not be zero.') print(e) print(divison(3,0)) # [Error]: Divisor can not be zero. # division by zero # None ``` ## Raise語法 用Raise顯示Exception ```python= def chkPWD(pwd): pwdlen = len(pwd) if pwdlen > 6: raise Exception('password is too long.') if pwdlen < 4: raise Exception('password is too short.') else: print('password correct!') for pwd in ('abcdefg', 'abc', 'abcd'): try: chkPWD(pwd) except Exception as err_msg: print('Error occurs during password checking: ', str(err_msg)) # 所有皆有執行 # Error occurs during password checking: password is too long. # Error occurs during password checking: password is too short. # password correct! ``` ## Assert語法 Assert可以幫助檢查變數是否符合期望,若不符合則產生例外 ```python= def chkPWD(pwd): pwdlen = len(pwd) assert pwdlen > 6, 'password is too long.' assert pwdlen < 4, 'password is too short.' print('password correct!') print(chkPWD('abc')) # 產生執行錯誤 # AssertionError: password is too long. ``` # :memo: 檔案處理(讀入、寫入) ## txt, csv檔案 CSV檔案為常見的資料儲存格式 定義:row之間用換行來區分,column用" ,"來區分 ![](https://i.imgur.com/QWdjW4L.png =300x) ### open() 1.讀檔 [Documentation: open()](https://docs.python.org/3/library/functions.html#open) ```python= #open後一定要close path = "stock.csv" f = open(path, "r", encoding = "UTF-8") print(f.name) #stock.csv print(f.closed) #False print(f.mode) #r f.close() print(f.closed) #True ``` ```python= #with as用法可以省略 with open('stock.csv', 'r', encoding="UTF-8") as f: data1 = f.read() print(data1) # Code,Name,Close Price,Change Percent,Today Amount,Last Day Amount,Last 2Day Amount # 2303,聯電,52.7,1.35,3967.0,5606.0,-2319.0 # 3545,敦泰,270.5,9.96,3012.0,962.0,227.0 # 2454,聯發科,933.0,1.52,1740.0,1547.0,-599.0 # 2603,長榮,154.0,7.32,1510.0,240.0,-9557.0 # 2338,光罩,101.5,6.06,1272.0,-624.0,907.0 # 2609,陽明,145.5,3.56,1260.0,-1026.0,-2362.0 # 2002,中鋼,36.3,3.12,1143.0,595.0,-970.0 # 1101,台泥,53.0,1.73,725.0,-216.0,138.0 # 2409,友達,20.7,5.08,708.0,-419.0,195.0 # 8261,富鼎,124.5,6.87,519.0,-19.0,-18.0 ``` ```python= #readlines() 每一行列成list with open('test1.txt', 'r', encoding="UTF-8") as f: data1 = f.readlines() print(data1) #['Python is powerful and fast;\n', 'plays well with other;\n', 'is open.'] ``` 2.寫檔 ```python= path = "test1.txt" f = open(path, "w", encoding = "UTF-8") txt = '''Python is powerful and fast; plays well with other; is open.''' f.write(txt) f.close() # Python is powerful and fast; # plays well with other; # is open. ``` ```python= #with as用法可以省略 txt = '''Python is powerful and fast; plays well with other; is open.''' with open('test1.txt', 'w', encoding="UTF-8") as f: data1 = f.write(txt) # Python is powerful and fast; # plays well with other; # is open. ``` ### Excel # :memo: Internal Module ## 1. re module (Pattern正規化) 用法:用來抓取符合規定規則之字串 ![](https://i.imgur.com/7DFuJKa.png) ![](https://i.imgur.com/AKqmHdz.png =720x380) ### **re.match()** 比對從第一字元開始是否與pattern相符(只要有一個地方錯就None) ```python= import re txt = 'hello, hey, hi, Salaheyo' x = re.match('\w*', txt) # \w == [a-z, A-Z, 0-9], * == 任意個數之character print(x) #<re.Match object; span=(0, 5), match='hello'> x = re.match('\w{5}, \w{2}', txt) print(x) #<re.Match object; span=(0, 9), match='hello, he'> ``` ```python= import re phonenumber = "02-222-1234, 03-333-1234" regex = "(\w{2})-\w{3}-\w{4}" x = re.match(regex, phonenumber) if x: print(x) #<re.Match object; span=(0, 11), match='02-222-1234'> print("Valid phone number") else: print("Invalid phone number") #Valid phone number ``` ```python= import re phonenumber = "(02)-222-1234, 03-333-1234" regex = "(\w{2})-\w{3}-\w{4}" x = re.match(regex, phonenumber) if x: print(x) #<re.Match object; span=(0, 11), match='02-222-1234'> print("Valid phone number") else: print("Invalid phone number") #Invalid phone number ``` 如果要完整比對需要在結尾加$ ```python= import re list1 = ['AB1234', 'A01234', '0A1234', '1234AB', '1234A0', '123401', '0A1234', 'BMW2299', 'ABC123', 'AB123'] regex = r'\d{4}\w{2}$|\w{2}\d{4}$|[A-Z]{3}\d{4}$' # 防止跳脫字元 for i in range(len(list1)): if re.match(cl_pattern, list1[i]): print("normal: ", list1[i]) else: print("Fail: ", i) ``` ### **re.search()** 搜尋任何有符合pattern的字串 ```python= import re txt = 'Surprise mother fucker' x = re.search(f'mother', txt) #f'XXX'表示''為字串 print(x) print(type(x)) ``` ```python= import re phonenumber = "(02)-222-1234, 03-333-1234" regex = "\w{2}-\w{3}-\w{4}" x = re.search(regex, phonenumber) if x: print(x) #<re.Match object; span=(15, 26), match='03-333-1234'> print("Valid phone number") else: print("Invalid phone number") #Valid phone number ``` ### **re.findall()** 搜尋任何所有滿足pattern的字串 ```python= import re txt = 'hello! 23 hi 111. how are 889.' pattern = '\d+' #\d == [0-9], + ==至少一個 x = re.findall(pattern, txt) print(x) #['23', '111', '889'] type=<list> ``` ```python= import re phonenumber = "02-222-1234, 03-333-1234" regex = r"\d{2}-\d{3}-\d{4}" #r"xxx",方便解除內部跳脫字元 x = re.findall(regex, phonenumber) if x: print(x) print("Valid phone number") else: print("Invalid phone number") #['02-222-1234', '03-333-1234'] #Valid phone number ``` ```python= import re ntu_id = "R05543049, B12345678, C87654321" regex = r"(\w{1}[0|1]\d{7})" #[1|2]表示有1 or 2 obj = re.findall(regex, ntu_id) if obj: print(obj) print("Vaild id number") else: print("Invaild id number") #['R05543049', 'B12345678'] ##Vaild id number ``` ## 2. collections [collections - 容器資料型態](https://docs.python.org/zh-tw/3/library/collections.html)