Python 學習筆記 === python所有東西都是物件e.g., int, float, string... ## Variable Types Multiple Assignment python可以這樣assign, 1指定給a,b,c ```clike= a=b=c=1 ``` 也可以多個type assign給多個變數a=1, b=2, c="john" ```clike= a, b, c = 1, 2, "john" ``` python有5種不同的standard data types - Numbers - String - List - Tuple - Dictionary ### list (串列) list就像陣列一樣,可以用append加入元素,可以存不同type元素 * append()從尾巴加入元素 * len()可以算list長度 * sum()可以計算list中所有數值的加總(但list中的元素都需為數值,不可與字串混合) * count則是可以計算list中某個元素出現次數 * remove() 刪除元素 or 項目 * sort() * extend() +=來結合串列 * insert(), del與位移值來新增與刪除一個項目 python中 元素從0開始 [1:5] 代表從元素1到元素4,沒有包含元素5 ```clike= list=[] list.append(1) list.append(2) list2=[11,"hi", 3.8, 332] print (len(list)) #list串列長度 print (sum(list)) #串列元素總和 print (list2.count(11)) #計算list中某元素出現次數 print (list[0], list2[-1], list2[-2], list2[1:3]) #list2[1:3]從第1個元素到第2個元素,不包含第3個 print (list2[2:]) #從第2個元素開始到最後 ----------- output: 2 3 1 1 332 3.8 ['hi', 3.8] [3.8, 332] ``` **insert()** 插入元素 ```clike= >>> animal=['cat','dog','bird'] >>> animal.insert(2,'fish') >>> animal ['cat', 'dog', 'fish', 'bird'] ``` **extend() +=** 來結合串列 ```clike= >>> animal=['cat','dog','bird'] >>> car=['super','lambo','benz'] >>> animal.extend(car) >>> animal ['cat', 'dog', 'bird', 'super', 'lambo', 'benz'] ``` **remove()** 刪除元素 ``` >>> animal=['cat','dog','bird'] >>> animal.remove('cat') >>> animal ['dog', 'bird'] ``` **pop**來取得元素並刪除它,pop(0)為串列的開頭,pop()與pop(-1)為串列尾巴 ``` >>> animal ['cat', 'dog', 'bird'] >>> animal.pop(1) 'dog' >>> animal ['cat', 'bird'] >>> animal.pop() 'bird' >>> animal.pop(0) 'cat' ``` **index()** 來取得元素的位置 ``` >>> animal ['cat', 'dog', 'bird'] >>> animal.index('bird') 2 >>> 'dog' in animal #用in來測試某個值 True >>> 'fly' in animal False ``` **join()** 來轉換成字串 與split()相反,可以把字串串列結合成一個字串 ``` >>> ','.join(animal) 'cat,dog,bird' >>> ''.join(animal) 'catdogbird' >>> joined = '*'.join(animal) >>> joined 'cat*dog*bird' >>> separated = joined.split(',') #沒有','字元所以不會分開 >>> separated ['cat*dog*bird'] >>> separated = joined.split('*') >>> separated ['cat', 'dog', 'bird'] ``` 用sorted會回傳副本 用sort會直接排列原本的串列 ```clike= >>> sored = sorted(animal) >>> sored ['bird', 'cat', 'dog'] >>> animal ['cat', 'dog', 'bird'] >>> animal.sort() >>> animal ['bird', 'cat', 'dog'] ``` 如果用append就會變成一個串列的項目(元素),而不是合併裡的項目 ```clike= >>> food=['ham','vegetagles'] >>> animal.append(food) >>> animal ['cat', 'dog', 'bird', 'super', 'lambo', 'benz', ['ham', 'vegetagles']] >>> del animal[3] #刪除super >>> animal ['cat', 'dog', 'bird', 'lambo', 'benz', ['ham', 'vegetagles']] ``` 用copy來複製陣列 如果只是用b = animal,b只是參考到animal這個物件,並不會做copy動作 ```clike= >>> b = animal.copy() >>> b ['tiger', 'cat', 'dog'] ``` b c d是a的複本,他們都是新的物件~ ```clike= >>> a=[1,2,3] >>> b = a.copy() >>> c = list(a) >>> d = a[:] >>> a[0]='hello' >>> a ['hello', 2, 3] >>> b [1, 2, 3] >>> c [1, 2, 3] >>> d [1, 2, 3] ``` **串列的串列** 類似二維陣列 or 可以變成多維陣列 ```clike= >>> animal=['cat','dog','bird'] >>> car=['super','lambo','benz'] >>> all=[animal,car] >>> print(all) [['cat', 'dog', 'bird'], ['super', 'lambo', 'benz']] >>> all[0] ['cat', 'dog', 'bird'] >>> all[0][2] 'bird' ``` ### Tuple 在Python中,Tuple就像是串列(List),不過==串列是可變動(Mutable)物件==,而==Tuple是不可變動(Immutable)物件==。你可以使用( )來建立Tuple物件,也可以直接逗號區隔元素來建立Tuple物件。例如: Like string indices, tuple indices start at 0, and they can be sliced, concatenated, and so on //tuple 是從0開始,可以被切割,串接 ```clike= #tuple tup1 = ('physics','chemistry', 1997, 2000) tup2 = (1,2,3,4,5,6,7) print("tup1[0]:",tup1[0]) print("tup2[1:5]", tup2[1:5]) # 1 ~ 4元素 tup3 = tup1 + tup2 print(tup3) del tup3 #刪除tuple 3 ---------------- tup1[0]: physics tup2[1:5] (2, 3, 4, 5) ('physics', 'chemistry', 1997, 2000, 1, 2, 3, 4, 5, 6, 7) ``` 定義tuple的是逗號,可以不加() 可以用tuple()來轉換成tuple ```clike= >>> tuple = 'gu','ch' >>> tuple ('gu', 'ch') >>> tuple = ('gu','ch') >>> tuple ('gu', 'ch') -------- >>> a,b=tuple #可以一次指派給多個變數 >>> a 'gu' >>> b 'ch' -------- >>> fruit = 'apple' >>> car = 'cybertruck' >>> fruit,car = car,fruit #可以在一個expression中使用tuple來交換值 >>> fruit 'cybertruck' >>> car 'apple' ``` ### dictionary (字典) 就像是hash table一樣,以{key:value}方式儲存 ```clike= dict={'Jane':123,'Mark':456} dict['happy']=873 dict['smile']=445 print(dict) del dict['smile'] #刪除smile元素 print(dict) print (dict.keys()) #把key印出來 print (dict.get('Jane')) # print (dict.get('ann')) ------------------- output: {'Jane': 123, 'Mark': 456, 'happy': 873, 'smile': 445} {'Jane': 123, 'Mark': 456, 'happy': 873} dict_keys(['Jane', 'Mark', 'happy']) 123 None ``` 用update()來更新dict,clear()來刪除所有項目 ```clike= >>> other = {'cat':789} >>> dict.update(other) >>> dict {'Jane': 123, 'Mark': 456, 'cat': 789} >>> dict.clear() >>> dict {} >>> 'Jane' in dict #用in來 True ``` ```clike= >>> lol = [['a','b'],['c','d'],['e','f']] #串列的串列 >>> dict(lol) {'a': 'b', 'c': 'd', 'e': 'f'}        #轉成dict >>> lot = [('a','b'),('c','d'),('e','f')] #含有tuple的串列 >>> dict(lot) {'a': 'b', 'c': 'd', 'e': 'f'} >>> tol=(['a','b'],['c','d'],['e','f']) #含有串列的tuple >>> dict(tol) {'a': 'b', 'c': 'd', 'e': 'f'}   >>> los = ['ab','cd','ef']         #含有字串的串列 >>> dict(los) {'a': 'b', 'c': 'd', 'e': 'f'} >>> tos = ('ab','cd','ef')         #含有字串的tuple >>> dict(tos) {'a': 'b', 'c': 'd', 'e': 'f'} ``` ### set (集合) set就是集合,可以進行聯集、交集、差集等運算 與字典一樣set是無序的 ```clike= admin = set() users={'smile','kent','Happy','Sherry','Allen'} admin.add('Mars') admin.add('Allen') print (admin & users) print (admin | users) print (admin ^ users) #取or 但相同的會被刪除 print (admin - users) #admin中有users的元素會被刪除,屬於第一個集合但是不屬於第二個集合 print (users - admin) #user 中有admin的元素會被刪除 ---------------------- output: {'Allen'} {'smile', 'Allen', 'Sherry', 'Mars', 'Happy', 'kent'} {'smile', 'Sherry', 'Mars', 'Happy', 'kent'} {'Mars'} {'smile', 'Happy', 'kent', 'Sherry'} ``` set與字典的應用,建立一個drinks的字典,每個key值為一種飲料的名稱,其值對應到它的材料,就算集合是用{}但它們只是一系列的值,字典是一或多個key:value對 ```clike= 1 #!/bin/python3 2 3 drinks = { 4 'martini':{'vodka','vermouth'}, 5 'black russian':{'vodka','kahlua'}, 6 'white russian':{'cream','kahlua','vodka'}, 7 'screwdriver':{'orange juice','vodka'} 8 } 9 10 for name, contents in drinks.items(): 11 if 'vodka' in contents: 12 print(name) 13 print("--------------------") 14 15 for name, contents in drinks.items(): 16 if 'vodka' in contents and not('vermouth' in contents or 17 'cream' in contents): 18 print(name) 19 20 print("--------------------") 21 22 for name, contents in drinks.items(): 23 if contents & {'vermouth', 'orange juice'}: 24 print(name) $ python set.py martini black russian white russian screwdriver -------------------- black russian screwdriver -------------------- martini screwdriver ``` ### string(字串) `\n` 表示換行,`\t`表示tab ```clike= >>> palindrome = 'A man, \nA plane, \nA canal, \nPannama' >>> print(palindrome) A man, A plane, A canal, Pannama >>> print('\tabc') abc ``` `\'` 單引號, `\"`雙引號 , `\\` 反斜線 ``` >>> testimony = "\"I did nothing !\" he said." >>> print(testimony) "I did nothing !" he said. >>> >>> speech = 'Today we honor our friend, the backlash: \\.' >>> print(speech) Today we honor our friend, the backlash: \. ``` `*`可以用來複製字串 ``` >>> 'na' *4 'nananana' ``` split()來切割字串 ```clike= >>> birthday='1/6/1952' >>> birthday.split('/') ['1', '6', '1952'] ----------- >>> N.split() ['remove', '3'] >>> s=N.split() >>> s ['remove', '3'] >>> s[0] 'remove' >>> s[1] '3' ``` ```clike= s="Hello" s += " world" s1= s.replace("ll","RR") #將ll替代成RR s2= "hello"[0]+"i" #將"hello"第0個元素取出+"i" -> "hi" print (s) print (s1) print (s2) print (len(s1)) #有包含中間空字元,沒有NULL character ----------------- Output: Hello world HeRRo world ei 11 ``` 字串 tuple 都是從0開始, [-1]代表最後一個字元 ``` letter = 'abcdef' 012345 a b c d e f -6 -5 -4 -3 -2 -1 >>> letter = 'abcdef' >>> letter[0] 'a' >>> letter[-1] 'f' >>> letter[-2] 'e' >>> letter[1] 'b' ``` ```clike= var=" 'hello world'" #印出單引號 var1="happy new year" var2="Python programming" var3="Python" #var[start:end(不包含end字元)] , [:end]沒有指定代表從頭開始 print("update string:",var1[:5], var2[7:]) print (var) print (var3[:5:2]) # [i:j:k] 從i到j(不含)中,切出每間格k元素的內容 print (var3[::-1]) # k為負時,代表負偏移k個元素,此結果為反轉字串 var1_split=var1.split(' ') print (var1_split) ----------------- Output: update string: happy programming 'hello world' Pto nohtyP ['happy', 'new', 'year'] ``` strip 可以移除空白字元(' ') ('\t') ('\n') ## 字串格式化: 與C一樣可以把依照格式輸出 ```clike= print ("My name is %s and weight is %d kg!" % ('Zara', 21)) Output: My name is Zara and weight is 21 kg! ``` 在Python3(或Python 2.6)中導入了新的格式化字串方法,可以讓你根據位置、關鍵字(或兩者混合)來進行字串格式化,例如: ```clike= >>> '{0} is {1}!!'.format('Justin', 'caterpillar') 'Justin is caterpillar!!' >>> '{real} is {nick}!!'.format(real = 'Justin', nick = 'caterpillar') 'Justin is caterpillar!! ``` ```clike= >>>"{} {}".format("hello", "world") # 不设置指定位置,按默认顺序 'hello world' >>> "{0} {1}".format("hello", "world") # 设置指定位置 'hello world' >>> "{1} {0} {1}".format("hello", "world") # 设置指定位置 'world hello world' ``` ## 變數 Python3 print要加(), python2可以用print Python是動態語言,也就是變數本身並沒有型態資訊,型態的資訊是在執行時期的物件之上,在Python中要建立變數,無需宣告型態,只要命名變數並指定值給它,就建立了一個變數,變數在Python中只是一個參考(而所有的資料都是物件 e.g., 一開始x參考至1整數物件,之後+運算後,建立了新的2整數物件,而後指定給x,所以x參考至新的物件,可以看到x的位置已經改變 **id()** 函式來取得所參考物件的記憶體位址代表數字 ```clike= >>> x = 1 >>> id(x) 505389048 >>> x = x + 1 >>> id(x) 505389064 >>> ``` ```clike= x=10 y=x print(id(x),id(y)) x=x+1 print(id(x),id(y)) #字串格式化 text='%d %.2f %s'%(1, 66.4, 'justin') x=[1,2,3] #串列 x2=(10,20,30) # print(text) print(x.index(2))   #找出串列中2的值的位置 print(x2.index(30)) #找出串列中30的值的位置 ---------------------- Output: (12894336, 12894336) (12894312, 12894336) 1 66.40 justin 1 2 ``` ## forloop 指定範圍或索引的需求,則可以使用range()類別產生一個range物件 range(start, stop, step),忽略start範圍會從0開始,stop是必要值,最後產生的值是stop的前一個, ```clike= # -*- coding: UTF-8 -*- import sys for arg in sys.argv: # print出輸入的參數 print(arg) my_set=[(1, 2), (10, 20), (100, 200)] for (a,b) in my_set: print(a,b) for index in range (5): # print 從0 ~ 4, stop值的前一個 print(index) my_list=[] for i in range(0,10): # for(i=0; i<10 ;i++) my_list.append(i+1) for i in my_list: print(i, end=" ") # 預設會換行,加入end=" "表示結為不換行加入空格 print("\n") ----------------------------------- ds@dason-pc:~/python$ python3 for.py hello world to you for.py hello world to you 1 2 10 20 100 200 0 1 2 3 4 1 2 3 4 5 6 7 8 9 10 ``` 用**range**來產生數字序列 range (start, stop, step),如果沒有start範圍從0開始,stop是唯一必要的, step的預設值是1,但可以用-1往回走 ```clike= >>> list(range(0,11,2)) [0, 2, 4, 6, 8, 10] ``` #### 用for來迭代 Python經常使用迭代器,迭代器可以讓你在不知道資料有多大情況下來遍歷它們,甚至可以迭代動態建立的資料,處理不適合被全部放在電腦記憶體內的資料串流。 ```clike= def use_no_iter(): rabbits = ['Flopsy','Mopsy','Conttontal','Peter'] current = 0 while current < len(rabbits): print(rabbits[current]) current += 1 def use_iter(): rabbits = ['Flopsy','Mopsy','Conttontal','Peter'] #可迭代的python物件 for rab in rabbits: print(rab) ---------------- $ python3 while.py Flopsy Mopsy Conttontal Peter ``` **可迭代的python物件:** string,tuple,字典,集合..   e.g,. 迭代**字串**一次會產生一個字元 ```clike= >>> word = 'cat' >>> for letter in word: >>> for letter in word: ... print(letter) ... c a t ``` 迭代**字典**會回傳key值, ```clike= >>> accusation = {'room':'ballroom', 'weapon':'lead pipe', ... 'person':'col'} >>> for card in accusation: ... print(card) ... room weapon person ``` 如果要取得**value**而不是key值,則用values()函式 ```clike= >>> for value in accusation.values(): ... print(value) ... ballroom lead pipe col ``` 要用tuple來回傳key與value可以使用items()函式 ```clike= >>> for item in accusation.items(): ... print(item) ... ('room', 'ballroom') ('weapon', 'lead pipe') ('person', 'col') ``` [迭代器 (Iterator)](https://wiki.jikexueyuan.com/project/explore-python/Advanced-Features/iterator.html) ### while 記得if or while後面要加: ```clike= print('enter two number') m=int(input('number1:')) n=int(input('number2:')) while n!=0: r=m%n m=n n=r print("gcd:",m) while True: number=int(input('enter num:')) print('enter', 'odd' if number%2 else 'even') if(input('carry on ?(yes/no)') == 'no'): break -------------------- enter two number number1:12 number2:3 gcd: 3 enter num:8 enter even carry on ?(yes/no)no ``` ### if else 乍看之下,else似乎是與第一個if配對,但實際上,else是與最近的if配對,也就是第二個if。但在Python中沒有這個問題 ```clike= if ...: if ...: dosomething() else: doother() ``` Python以縮排作為區塊依據,以上例而言,else是與第一個if配對,如果是下例,則else是與第二個if配對: ```clike= if ...: if ...: dosomething() else: doother() ``` ```clike= import sys filename= 'default.properties' if len(sys.argv) == 1 else sys.argv[1] #if len(sys.argv)!=1: # filename = sys.argv[1] print(filename) ``` ## def 在Python中不支援其它語言函式重載的概念(例如Java),也就是在Python中同一個名稱空間中,不能有相同的函式名稱。如果你定義了兩個函式具有相同的名稱但擁有不同的參數個數,則後者定義會覆蓋前者定義。例如: ```clike= >>> def sum(a, b): ... return a + b ... >>> def sum(a, b, c): ... return a + b + c ... >>> sum(1, 2, 3) 6 >>> sum(1, 2) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: sum() takes exactly 3 positional arguments (2 given) ``` 由於Python是動態語言,只需在設計時確認傳入函式的物件所擁有的特性或方法,無需採函式重載中,依型態不同來區別所呼叫函式的部份,至於依參數個數不同來區別的函式重載概念,在Python中可以使用預設引數(Argument)來解決。例如: ```clike= def sum(a, b, c = 0): return a + b + c print(sum(10, 20, 30)) # 顯示 60 print(sum(10, 20)) # 顯示 30 print(sum(c=30, a= 10, b=20)) # 不一定要照順序來傳入引數 ``` 傳入函式的引數,會被收集在一個==Tuple==中,再設定給numbers參數。有趣的是,如果你有個函式擁有固定的參數,你可以將一個Tuple傳入,只要在傳入時加上*,則Tuple中每個元素會自動指定給各個參數。例如: ```clike= def sum3(a,b,c): return a+b+c numbers = (1,2,3) print(sum3(*numbers)) #傳入參數固定可以用tuple傳入 ``` **則可以將關鍵字引數收集在一個==字典物件==中,當一個函式所需要的參數個數很多時,可以使用這個方式。例如: ```clike= def dosome(**args): print(args) dosome(name = 'Justin', passwd = 12345 , jog = '?') args = {'a':1, 'b':2, 'c':3} print(sum3(**args)) ------------------------------ {'name': 'Justin', 'passwd': 12345, 'jog': '?'} 6 ``` ## 模組 xmath.py 定義一些數學的function ```clike= def max(a, b): return a if a > b else b def min(a, b): return a if a < b else b def sum(*numbers): # numbers 接受可變長度引數 total = 0 for number in numbers: total += number return total pi = 3.141592653589793 e = 2.718281828459045 ``` 在call_xmath.py 用import 來引用xmath裡的function, import的名稱為檔名,只要你建立了一個原始碼檔案 modu.py,你就建立了一個模組 modu,原始碼主檔名就是模組名稱。 ```clike= import xmath print('# import xmath') print(xmath.pi) print(xmath.max(10, 5)) print(xmath.sum(1, 2, 3, 4, 5)) print('# import xmath as math') import xmath as math # 為 xmath 模組取別名為 math print(math.e) print('# from xmath import min') from xmath import min # 將 min 複製至目前模組,不建議 from modu import *,易造>成名稱衝突 print(min(10, 5)) ``` # 類別(class) bank.py 一個含有帳戶建立、存款、提款等函式 ```clike= def account(name, number, balance): return {'name': name, 'number': number, 'balance': balance} def deposit(acct, amount): if amount <= 0: raise ValueError('amount must be positive') acct['balance'] += amount def withdraw(acct, amount): if amount > acct['balance']: raise RuntimeError('balance not enough') acct['balance'] -= amount def to_str(acct): return 'Account:' + str(acct) ``` bank 中的函式操作,都是與傳入的 dict 實例,也就是代表帳戶狀態的物件高度相關,可以將它們組織在一起,這樣比較容易使用些,因此你重新使用類別組織了 bank.py 中的函式: ```clike= class Account: def __init__(self, name, number, balance): self.name = name self.number = number self.balance = balance def deposit(self, amount): if amount <= 0: raise ValueError('amount must be positive') self.balance += amount def withdraw(self, amount): if amount > self.balance: raise RuntimeError('balance not enough') self.balance -= amount def __str__(self):#自定義__str__ 在print(acct)會印出資訊 return 'Account({0}, {1}, {2})'.format(##python3的string format self.name, self.number, self.balance) ``` use_bank.py ```clike= import bank acct = bank.Account('Eric', '123-456', 1000) acct.deposit(500) acct.withdraw(200) print(acct) --------------- tesheng@node:~/python$ python3 use_bank.py Account(Eric, 123-456, 1300) ``` ## if__name__='__main__' 當python intepreter在執行某個.py檔為主要的program時候會將__name__設置為__main__,如果是從另一檔案呼叫此py檔案時候 參數會是檔案的名稱 name.py ```clike= print("always executed") if __name__=="__main__": print ("Excuted when invoked directly") print ("__name__:",__name__) else: print ("Excuted whe imported") ``` 直接執行 name.py 可以看到__name__參數為__main__ ``` $ python name.py always executed Excuted when invoked directly __name__: __main__ ``` call_name.py ```clike= print("call name.py") import name ``` 透過call_name.py 來import name 可以看到__name__參數為name.py檔案名稱 ``` $ python call_name.py call name.py always executed Excuted whe imported __name__: name ``` ## OOP ```clike= humay.py class Human: def __init__(self, h=0, w=0): self.height = h self.weight = w def BMI(self): return self.weight / (self.height/100)**2 class Woman(Human): def __init__(self, h, w, bust=0, waist=0, hip=0): super().__init__(h, w) self.bust = bust self.waist = waist self.hip = hip def printBWH(self): print("bust={}, waist={}, hip={}".format(self.bust, self.waist, self.hip)) ------------------------- call human.py import human a = human.Woman(165,54,83,64,84) print(a.BMI()) a.printBWH() ``` [[Python初學起步走-Day24] - 物件導向(Object-oriented,OO) - 定義類別](https://ithelp.ithome.com.tw/articles/10161285) [Python 面向对象](http://www.runoob.com/python/python-object.html) `__init__() `在 Python 類別 (class) 定義中是個特別的方法 (method) ,因為這個方法是在物件 (object) 建立的時候執行的,如同其他物件導向程式語言 (object-oriented programming language) 所講的建構子 (constructor) ```clike= __init__() ``` self代表的是class的實例(instance or object),而非class, 當創造一個object時`__init__`就會被調用 ```clike= #! /usr/bin/python3 class Test: def prt(self): print(self) print(self,__class__) t = Test() t.prt() class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart print("call __init__") x = Complex(3.0, -4.5) print(x.r, x.i) # 输出结果:3.0 -4.5 -------------------------- $ python3 test.py <__main__.Test object at 0x7f7bed2b2630> # print(self) <__main__.Test object at 0x7f7bed2b2630> <class '__main__.Test'> call __init__ 3.0 -4.5 ``` [Python-Constructor](https://pydoing.blogspot.com/2012/12/Python-Constructor.html) ## 修飾器decorator Python 中的函数和 Java、C++不太一样,Python 中的函数可以像普通變數一樣當作參數傳給另一個函數 ```clike= def foo(): print("foo") def bar(func): func() bar(foo) ``` 我們希望可以增加日誌的功能於是定一個use_logging的函數,處理完日誌後再執行函數,因此必須將foo函數作為參數,傳遞給use_logging函數,但是這樣 ```clike= #!/usr/bin/env python import logging def use_logging(func): logging.warning("%s is running" % func.__name__) func() def foo(): print('i am foo') use_logging(foo) ``` 注意縮排def下面都要tab ```clike= #!/usr/bin/env python import logging def use_logging(func): def wrapper(): logging.warning("%s is running" % func.__name__) return func() #把foo當作參數傳遞近來, return wrapper def foo(): print('i am foo') foo = use_logging(foo) #回傳warpper 函數給foo foo() #執行foo()就相當於執行wrapper() -------------------------------- $ ./decorator.py WARNING:root:foo is running i am foo ``` [理解 Python 装饰器看这一篇就够了](https://foofish.net/python-decorator.html) [Python進階技巧 (3) — 神奇又美好的 Decorator ,嗷嗚!](https://medium.com/citycoddee/python%E9%80%B2%E9%9A%8E%E6%8A%80%E5%B7%A7-3-%E7%A5%9E%E5%A5%87%E5%8F%88%E7%BE%8E%E5%A5%BD%E7%9A%84-decorator-%E5%97%B7%E5%97%9A-6559edc87bc0) ## Debug 會出現這個表示檔案裡面有中文字,要在第一行加入`# -*- coding: UTF-8 -*-` ```clike= “Non-ASCII character 'xe5' in file” ``` ## 開啟檔案 ```clike= fin = open('p550mc.txt','r') while True: #data = fin.read().rstrip() lines = fin.read() if not lines: break print(lines) fin.close or 5 with open('test.txt','r') as f: 6 for line in f: 7 # EventCode 8 encode = line.strip().split()[0] 9 print(encode) 10 event_encode = {"EventCode": encode} 11 # event_encode_json = json.dumps(event_encode) 12 print(event_encode) ``` line.strip() 先移除換行 \n line.strip().split()[0] 會切出0x102 ```clike= $ cat test.txt 0x102 Instruction cache miss 0x202 Data cache miss or memory-mapped I/O access 0x402 Data cache write-back ------------- $ python3 test.py 0x102 {'EventCode': '0x102'} {"BriefDescription": "Instruction cache miss"} {"EventName": "INSTRUCTION_CACHE_MISS", "EventCode": "0x102", "BriefDescription": "Instruction cache miss"} ``` #### 判斷是不是最後一個元素 ```clike= //跳過第一個元素 16 for line1 in line.strip().split()[1:]: 17 if line1 == line.strip().split()[-1]: 18 string += line1 19 else: 20 string += line1 + "_" ``` ```clike= my_list = ['one', 'two', 'three', 'four'] for index, item in enumerate(my_list): if index != len(my_list) - 1: print(item, 'is NOT last in the list ✅') else: print(item, 'is last in the list ❌') ``` **Ref:** https://bobbyhadz.com/blog/python-detect-last-item-in-list-for-loop ### json.dump vs json.dumps json.dumps() 是把python對象轉換成json對象的一個過程,生成的是字符串 json.dump() 是把python對象轉換成json對象生成一個fp的文件流,和文件相關 ```clike= 39 event = { 40 "EventName": string.upper(), 41 "EventCode": encode, 42 "BriefDescription": string2 43 } 44 event_json = json.dumps(event) 45 print(event_json) ---------------- {"EventName": "DATA_CACHE_WRITE-BACK", "EventCode": "0x402", "BriefDescription": "Data cache write-back"} ``` ```clike= 36 json.dump(list, fp, indent = 2) ``` ### Nested Json python ```clike= { "id": 123, "Name": "wsrsw", "Email": "wsrsw@example.com", "contents": [ { "subject":"Math", "score":80 }, { "subject":"English", "score":90 } ] } ``` ```clike= //parse_om_encoding.py #!/bin/python3 import json import numpy as np def get_vals(nested, key): result = [] if isinstance(nested, list) and nested != []: #non-empty list for lis in nested: result.extend(get_vals(lis, key)) elif isinstance(nested, dict) and nested != {}: #non-empty dict for val in nested.values(): if isinstance(val, (list, dict)): #(list or dict) in dict result.extend(get_vals(val, key)) if key in nested.keys(): #key found in dict result.append(nested[key]) return result with open('x.json', 'r') as f: arr = json.load(f) con = get_vals(arr, 'score') print(con) ``` 找到key符合的value都會加入到array ```clike $ python3 parse_om_encoding.py [80, 90] ``` ### pyFDT https://github.com/molejar/pyFDT ### detect python lib path ```clike $ python3 Python 3.7.5 (default, Dec 9 2021, 17:04:37) [GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> print(sys.path) ['', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/home/ericl/.local/lib/python3.7/site-packages', '/usr/local/lib/python3.7/dist-packages', '/usr/lib/python3/dist-packages'] >>> ``` ```clike! $ find /usr/lib/python3.7/ -name "libpython*" /usr/lib/python3.7/config-3.7m-x86_64-linux-gnu/libpython3.7m.so /usr/lib/python3.7/config-3.7m-x86_64-linux-gnu/libpython3.7.so /usr/lib/python3.7/config-3.7m-x86_64-linux-gnu/libpython3.7m-pic.a ``` **Ref:** [Openhome Python](https://openhome.cc/Gossip/Python/) [Python - 十分鐘入門](http://tech-marsw.logdown.com/blog/2014/09/03/getting-started-with-python-in-ten-minute) [Python 3 Tutorial](https://www.tutorialspoint.com/python3/python_strings.htm) [python101](https://blog.techbridge.cc/2016/12/17/python101-tutorial/) [Python 3 Tutorial 第一堂](https://openhome.cc/Gossip/CodeData/PythonTutorial/index.html) [精通python書籍]() [python-tricks](https://haosquare.com/python-tricks/) [Working With Large Nested JSON Data](https://ankushkunwar7777.medium.com/get-data-from-large-nested-json-file-cf1146aa8c9e) [how-do-i-parse-nested-json-objects](https://stackoverflow.com/questions/67796119/how-do-i-parse-nested-json-objects) [pyFDT](https://github.com/molejar/pyFDT)