此篇是集結 Python 所有的基礎語法內容,我將此篇當作學習筆記,需要用到時才回來複習,但未覆蓋到 List Unpacking 的用法, 關於 List Unpacking 的使用方式可以參考 Mike 的這篇文章 Python Unpacking實用技巧分享
Data Type
int
float
bool
str
list: 動態的 Array, Javascript Array 類似
tuple: 可以想成是 immuable 的 list
set: collection of uniqe values
dict: Javascript 的 Object, Java 的 HashMap
Ternary Expression is_lisenced = True word = "I can sense that lisence in you" if is_lisenced else "get out"
Truthy and Falsey 以下為 Falsey 值, 其他皆視為 Truthy 值
None
False
0
0.0
0j
decimal.Decimal(0)
fraction.Fraction(0, 1)
[]
- an empty list
{}
- an empty dict
()
- an empty tuple
''
- an empty str
b''
- an empty bytes
set()
- an empty set
an empty range
, like range(0)
objects for which
obj.__bool__()
returns False
obj.__len__()
returns 0
is vs == ==
檢查值是否相同, 如果非相同的型別,python 會試著轉型別
print (True == 1 ) print ('' == 1 ) print ([] == 1 ) print (10 == 10.0 ) print ([] == [])
is
檢查記憶體地址是否相同
print (True == 1 ) print ('' == 1 ) print ([] == 1 ) print (10 == 10.0 ) print ([] == [])
for Loops and Iterator for item in 'Brian' : print (item)
Iterate Object user = { "name" : "Brain" , "age" : 28 , "can_swim" : True } for item in user.items(): print (item) for key, value in user.items(): print (key, value)
用 range() for item in range (100 ): print (item)
如果你不需要用參數的話:
for _ in range (100 ): print ('haha' )
while loop i = 0 while i < 50 : print (i) i += 1 else : print ('Done with all the work' )
如果用 Break 的話就不會跑 else 的程式
i = 0 while i < 50 : print (i) i += 1 break else : print ('Done with all the work' )
continue 在迴圈裡用 continue, 就會略過迴圈裡 continue 以後的程式,直接跑下一個迴圈
my_list = [1 , 2 , 3 ] for item in my_list: print ('haha' ) continue print (item) i = 0 while i <len (my_list): print (my_list[i]) i += 1 continue print (i)
Function *args
跟 *kwargs
*_args: _ 將所有的 arugements 轉為 tuple
def super_func (*args ): print (args) super_func(1 , 2 , 3 , 4 , 5 )
*_kwargs: _ 將所有的 arguments 轉為 dict
def super_func (**kwargs ): print (kwargs) super_func(name='Brian' , age=27 )
同時使用
def super_func (*args, **kwargs ): print (args) print (kwargs) super_func(1 , 2 , 3 , name='Brian' , age=27 )
如果要使用多種不同的參數 順序: params, *args, default params, **kwargs
Function Docstring 可以利用 docstring 幫 function 進行註解
def test (): ''' Info: this function tests and prints param a string ''' print ('Hello world' )
Walrus Operator Before:
a = 'Helloooooooooooo' if (len (a) > 10 ): print (f"Too long {len (a)} letters" )
After:
a = 'Helloooooooooooo' if ((n := len (a)) > 10 ): print (f"Too long {n} letters" )
變數 Scope 順序為
是否為 local 變數
是否為 parent 層 local 變數
是否為 global 變數
是否為內建 method
global 如果要在 function 裡, 用 global 的變數, 則需要用 global
keyword
totoal = 0 def count (): global total total += 1 return total print (count())
但不推薦這麼做,可以直接將 global 的變數丟進 function 裡閱讀性較好
nonlocal 在 function 裡使用 parent function 的變數, 則需要用 nonlocal
keyword
def outter (): x = "local" def inner (): nonlocal x x = "nonlocal" print (x) inner() print ("outer:" , x) outer()
class class Player (): def __init__ (self, name ): self.name = name def run (self ): print ('run' )
@classmethod, @staticmethod 用來新增 class 本身的 method, 不需要 instantiate 就可以使用
與一般 method 不同,@classmethod
的第一個參數是自己本身的 class, @staticmethod
則沒有任何預設參數
class Player (): def __init__ (self, name ): self.name = name @classmethod def sum (cls, num1, num2 ): return num1+num2 @staticmethod def sum2 (num1, num2 ): return num1+num2
Inheritance 子 class 需要利用該 Class名稱.__init__()
或是 super().__init__()
將父 class init 需要的直傳入Class名稱.__init__()
: 第一個參數要傳入 self
class Person (): def __init__ (self, name, age ): self.name = name self.age = age def greeting (self ): print (f'Hello, my name is {self.name} and i am {self.age} years old' ) class Wizard (Person ): def __init__ (self, name, age, power ): Person.__init__(self, name, age) self.power = power
super().__init__()
: 不需傳入 self
class Person (): def __init__ (self, name, age ): self.name = name self.age = age def greeting (self ): print (f'Hello, my name is {self.name} and i am {self.age} years old' ) class Wizard (Person ): def __init__ (self, name, age, power ): super ().__init__(name, age) self.power = power def attack (self ): print (f'attacking with power of {self.power} ' )
Multiple Inheritance class Wizard : def __init__ (self, name, power ): self.name = name self.power = power def magic_attack (self ): print (f'{self.name} shoot the magic fire ball with {self.power} damage' ) class Archer : def __init__ (self, name, arrow_count ): self.name = name self.arrow_count = arrow_count def shoot_arrow (self ): print (f'{self.name} shoot {self.arrow_count} arrows' ) class HybridMan (Wizard, Archer ): def __init__ (self, name, power, arrow_count ): Wizard.__init__(self, name, power) Archer.__init__(self, name, arrow_count) super_man = HybridMan('Super Man' , 10000 , 500 ) super_man.magic_attack() super_man.shoot_arrow()
MRO - Method Resolution Order class A : num = 10 class B (A ): pass class C (A ): num = 1 class D (B, C ): pass print (D.num)
Dunder Methods python 裡所有東西都是 object, 當我們在創建一個物件時,就會繼承底層 object 的 methods, 所有你看到的 __xxx__
屬性都是繼承底層 object 來的 method, 但我們也可以通過覆寫去重新實作這些 method
假設我們想要覆寫 __str__
method
class Toy (): def __init__ (self, color ): self.color = color def __str__ (self ): return f'{self.color} ' toy = Toy('Yellow' ) print (toy.__str__()) print (str (toy))
__name__
: 檔案(模組)的名稱, 如果是執行的檔案則是 __main__
functional programming Build in methods map
my_list = [1 , 2 , 3 ] def multiply (num ): return num * 2 mapObject = map (multiply, my_list) new_list = list (mapObject)
filter
test_list = [1 , 2 , 3 ] def is_odd (num ): return num % 2 != 0 odd_numbers = list (filter (is_odd, test_list))
zip
test_list = [1 , 2 , 3 ] test_list2 = ["David" , "Amy" , "John" ] def is_odd (num ): return num % 2 != 0 zipped_list = list (zip (test_list, test_list2)) print (zipped_list)
reduce
from functools import reducemy_list = [1 , 2 ,3 ] def accumulator (acc, number ): return acc + number print (reduce(accumulator, my_list, 0 ))
Lambda
語法: lambda param: action(param)
test_list = [1 , 2 , 3 ,] map (lambda num: num * 2 , my_list)list (filter (lambda num: num % 2 != 0 , my_list))reduce(lambda acc, num: acc + num, my_list, 0 ) a = [(0 ,2 ), (4 ,3 ), (9 ,9 ), (10 , -1 )] a.sort(key=lambda x: x[1 ]) print (a)
list, set, dictionary comprehension 這是一個只有 pythonthon 獨有的語法糖 before:
my_list = [] for char in "Heloo" : my_list.append(char)
after:
my_list = [char for char in 'hello' ]
其他範例:
my_list2 = [num for num in range (0 , 200 )]
如果我想讓 output 的數字都乘2
my_list2 = [num*2 for num in range (0 , 200 )]
加上 condition
my_list2 = [num**2 for num in range (0 , 100 ) if num % 2 == 0 ]
Dictionary Example:
my_dict = {num:num*2 for num in [1 ,2 ,3 ]} print (my_dict)
simple_dict = { 'a' : 1 , 'b' : 2 } my_dict = {key:value**2 for key, value in simple_dict.items()} print (my_dict)
加上 condition
simple_dict = { 'a' : 1 , 'b' : 2 } my_dict = {k:v**2 for k,v in simple_dict.items() if v%2 == 0 }print (my_dict)
Decorator Higher Order function 以下兩種都算是 higher order function
參數為 function
返回 function
def greet (): def func (): return 5 return func
Decorator function 的格式 只要符合以下格式就可以當 decorator function, 所以事實上 decorator 只是 higher order function 的語法糖
def my_decorator (func ): def wrap_func (): print ("開始執行~" ) func() print ("執行成功 😀😀😀😀" ) return wrap_func
使用:
@my_decorator def hello (): print ("我是一個 function" ) hello()
以下兩個語法相等 Higher Order Function 版:
def hello (): print ("我是一個 function" ) wrap_func = my_decorator(hello) wrap_func()
Decorator 版:
@my_decorator def hello (): print ("我是一個 function" ) hello()
傳參數 傳單個參數
def my_decorator (func ): def wrap_func (param ): print ("----------" ) func(param) print ("----------" ) return wrap_func
傳多個參數: 利用 list unpacking
def my_decorator (func ): def wrap_func (*args, **kwargs ): print ("----------" ) func(*args, **kwargs) print ("----------" ) return wrap_func
Error Handling Built-In Error
語法
while (True ): try : age = int (input ('What is your age?' )) 10 /age except : print ('Please enter a number' ) else : print ('Thank you!' ) break
抓特定 exception 這邊我們想要抓使用者打 0 的時候的,10/0 發生的錯誤,
while (True ): try : age = int (input ('What is your age?' )) 10 /age except ValueError: print ('Please enter a number' ) except ZeroDivisionError: print ('Please enter age higher than 0' ) else : print ('Thank you!' ) break
使用 Error 物件
def sum (num1, num2 ): try : return num1 + num2 except TypeError as err: print (f'Please enter numbers {err} ' )
一次抓取兩種錯誤
def sum (num1, num2 ): try : return num1/num2 except (TypeError, ZeroDivisionError) as err: print (f'Error: {err} ' )
利用 finally
keyword
while (True ): try : age = int (input ('What is your age?' )) except ValueError: print ('Please enter a number' ) except ZeroDivisionError: print ('Please enter age higher than 0' ) else : print ('Thank you!' ) break finally : print ('ok, i am finally done' )
用 raise
keyword主動發出 Error 有時候我們想要針對特定邏輯主動發起錯誤,這時候我們就可以用 raise
keyword
def sum (num1, num2 ): try : number = num1/num2 if (number < 0 ): raise ValueError('The number should be positive' ) return number except (TypeError, ZeroDivisionError) as err: print (f'Error: {err} ' )
Generator 語法 Example 01
def generator_function (num ): for i in range (num): yield i*2 generator = generator_function(100 ) print (next (generator)) print (next (generator)) print (next (generator))
Example 02
def gen_func (num ): for i in range (num): yield i for i in gen_func(10 ): print (i)
Modules 假設我現在除了 main.py
以外還以一個 utilities.py
的檔案在同一個檔案夾import 整個 file
import utilitiesnum = utilies.mutiply(2 , 3 )
import 個別變數和 methods 注意:如果 import 的 method 與 built in method 撞名, 會執行 import 的 method, 或是可以用 as
keyword 將 import 的 method 改名
from utilities import multiply, dividenum = multiply(2 ,3 )
如果要 import 檔案夾裡面的檔案,python 會把檔案夾當作是 package
import folder_name.file_namefrom folder_name.file_name import the_method