Review
function
recursion
decorator
lambda
class
例外處理
函式庫
鍵 ( Key ) - 值 ( Value ) 對應,key 需唯一且不可變
d = {'a': 1, 'b': 2}
d1 = {[1, 2]: 1} #TypeError: unhashable type: 'list'
dict methods
d = {'b': 2}
d['a'] = 1
print(len(d)) #2
print(list(d.keys())) #['b', 'a']
print(list(d.values())) #[2, 1]
print(list(d.items())) #[('b', 2), ('a', 1)]
print(d.get('a', "Doesn't exist")) #1
print(d.copy()) #{'b': 2, 'a': 1}
del d['a']
print(d) #{'b': 2}
將輸出內容格式化
a = "Hi, I am %s."
print(a % "pomelo") #Hi, I am pomelo.
b = "I have %d dollars."
print(b % 3.333) #I have 3 dollars.
c = "Now I have %f dollars."
print(c % 3.333) #Now I have 3.333000 dollars.
a = "Hello, I am {}, and I like to eat {}."
print(a.format("pomelo", "apple"))
#Hello, I am pomelo, and I like to eat apple.
b = "Hello, {:-^10s}."
print(b.format("world")) #Hello, --world---.
name = "pomelo"
age = 15.187
print(f"My name is {name}, I am {age} years old.")
#My name is pomelo, I am 15.187 years old.
print(f"Hello {name.upper()}, I am {age:-^.1f} years old.")
#Hello POMELO, I am 15.2 years old.
條件判斷
a = 1
b = 2
if a > b:
print("a > b")
elif a == b:
print("a == b")
else:
print("a < b")
#a < b
print(a and b) #2
print(a or b) #1
print(0 and b or a) #0
for 變數 in 可迭代物件/range():
lst = [1, 3, 4]
for i in lst:
if i > 2:
print(i)
#3 4
for i in range(0, 4, 2):
print(i)
#0 2
while 條件:
n = 4
while n > 0:
print(n, end=' ')
n -= 1
#4 3 2 1
給一個 x 值會對應到某個數值
def f(x):
result = x**2 + 2*x + 1
return result
print(f(2)) #9
define,定義函式需要的開頭
函式名稱
要傳入的參數
回傳值
執行函式
函式是一種有名稱且獨立的程式片段,可以接收任何型態的參數,處理完成後也可以輸出任何型態的結果
def 函式名稱(參數1, 參數2...): #定義函式
要執行的程式
return 回傳值
函式名稱(參數1, 參數2...) #執行函式
要先定義函式,才能執行
可以放入多個參數,會按照順序處理
def f(a, b):
return a - b
print(f(1, 2)) #-1 (a = 1, b = 2)
print(f(2, 1)) #1 (a = 2, b = 1)
最多只能輸入與參數數量一樣多的變數值
也可以不放入參數
def f():
return 6
print(f()) #6
可以用關鍵字引數設定特定參數內容
def mbi(weight, height):
return weight / (height**2)
print(mbi(height=1.5, weight=45)) #20.0
順序不一樣也沒關係
使用 return
回傳值
def f(x):
all = 0
for i in x:
all += i
return all
print(f([1, 2, 4])) #7
也可以不回傳值
def f(name):
print(f"Hello, {name}")
a = f("pomero") #Hello, pomero
print(a) #None
會回傳 None
遇到 return 時會中止函式並回傳值
def f(x):
all = 0
for i in x:
all += i
if i % 5 == 0:
return all
return all
print(f([1, 3, 5, 6])) #9
print(f([1, 3, 4, 6])) #14
def f(x):
all = 0
for i in x:
all += i
if i % 5 == 0:
return all
return all
print(f([1, 3, 5, 6])) #9
print(f([1, 3, 4, 6])) #14
all = 0
all = 1
all = 4
+1
+3
all = 9
+5
return
5 % 5 == 0
def f(x):
all = 0
for i in x:
all += i
if i % 5 == 0:
return all
return all
print(f([1, 3, 5, 6])) #9
print(f([1, 3, 4, 6])) #14
all = 0
all = 1
all = 4
+1
+3
all = 8
+4
all = 14
+6
return
end for
可以回傳多個結果
def f(x, y, z):
return x+1, y+1, z+1
a = f(1, 2, 3)
print(a) #(2, 3, 4)
會回傳 tuple
def f(x, y, z):
return x+1, y+1, z+1
a, b, c = f(1, 2, 3)
print(f"a = {a}, b = {b}, c = {c}")
#a = 2, b = 3, c = 4
會回傳 tuple
可以 unpacking 給多個變數
a = 2
def f(a):
a = 1
print(f"a is {a}")
在函式裡宣告的變數,生命只到函式結束,稱為區域 ( local ) 變數
在函式裡宣告的函式也一樣
def f1():
def f2():
print("Local: f2")
f2()
f1() #Local: f2
f2()
#NameError: name 'f2' is not defined
可以把區域變數變成全域 ( global ) 變數
a = 2
def f():
global a
a = 1 #不可寫作:global a = 1
print(f"Global a in func: {a}")
print(f"Before f(), global a = {a}")
f()
print(f"After f(), global a = {a}")
# Before f(), global a = 2
# Global a in func: 1
# After f(), global a = 1
可以修改上層函式中定義的變數
def f1():
a = 2
print(f"Local variable a = {a} in f1")
def f2():
print(f"f2 calls a = {a}")
def f3():
nonlocal a
a = 10
print(f"f3 calls modified a = {a}")
f3()
f2()
print(f"a in f1 = {a}")
f1()
# Local variable a = 2 in f1
# f2 calls a = 2
# f3 calls modified a = 10
# a in f1 = 10
def f1():
a = 2
print(f"Local variable a = {a} in f1")
def f2():
print(f"f2 calls a = {a}")
def f3():
nonlocal a
a = 10
print(f"f3 calls modified a = {a}")
f3()
f2()
print(f"a in f1 = {a}")
f1()
# Local variable a = 2 in f1
# f2 calls a = 2
# f3 calls modified a = 10
# a in f1 = 10
函式若未先在函式被呼叫不會執行
一個函式執行完裡面全部的內容後,才會執行另一個函式
可以傳入多個參數,傳入的參數會被轉為 tuple
def f(*s):
print(s)
f(1, 2, 3, 'a', 'b', 'c')
# (1, 2, 3, 'a', 'b', 'c')
用法:*變數名
可以傳入多個參數,傳入的參數會被轉為 dict
def f(**s):
print(s)
f(name='pomero', age=18, gender='g')
# {'name': 'pomero', 'age': 18, 'gender': 'g'}
用法:**變數名
使用之前要先賦值
若 *args 和 **kwargs 同時出現,會依照輸入的內容分別套用
def f(*args, **kwargs):
print(f"args: {args}")
print(f"kwargs: {kwargs}")
f([1, 2, 3], 4, x=1, y=2)
# args: ([1, 2, 3], 4)
# kwargs: {'x': 1, 'y': 2}
可以把函式當參數
def plus(a, f):
return a + f(a)
def square(a):
return a**2
print(plus(2, square)) #6 (2 + 2**2)
在函式裡呼叫自己或其他函數
def n(a):
if a < 1:
return 1
return a + n(a-1)
def fib(a):
if a == 1 or a == 2:
return 1
return fib(a-1) + fib(a-2)
print(fib(5)) #5
fib(5)
fib(4) + fib(3)
fib(3) + fib(2)
fib(2) + fib(1)
fib(2) + fib(1)
return 1
return 1
return 1
return 1
return 1
return 2
return 3
return 2
return 5
def fact(n):
if n == 0 or n == 1:
return 1
return n * fact(n-1)
print(fact(5)) #120
square = lambda x: x**2
print(square(2)) #4
使用:lambda 參數名稱: 內容
def hi():
print("Hi")
hi() #Hi
p = lambda l: print(l)
p("Hi") #H1
(lambda l: print(l))("Hi") #Hi
第 4 行執行結果跟第 5 ~ 6. 7 行一樣
不用使用小括號,需使用逗號分隔參數
POW = lambda x, y: x**y
print(POW(2, 4)) #16
f = lambda *args: print(args)
f(1, 2, 3) #(1, 2, 3)
也可以使用 *args
lambda 可以搭配 for 迴圈使用
def x(*args):
lst = []
for i in args:
lst.append(i*2)
return lst
y = lambda *args: [i*2 for i in args]
print(x(1, 2, 3)) #[2, 4, 6]
print(y(1, 2, 3)) #[2, 4, 6]
lambda 也可以搭配 if 使用
def x(n):
if n < 10:
return True
else:
return False
y = lambda n: True if n < 10 else False
print(x(11)) #False
print(y(11)) #False
為什麼不是印出 0, 1, 16 ?
square = []
for i in range(5):
square.append(lambda : i**2)
print(square[0]()) #16
print(square[1]()) #16
print(square[4]()) #16
為什麼不是印出 0, 1, 16 ?
square = []
for i in range(5):
square.append(lambda : i**2)
print(square[0]) #<function <lambda> at 0x7fcd4a364d30>
print(square[1]) #<function <lambda> at 0x7fcd4a364dc0>
print(square[4]) #<function <lambda> at 0x7fcd4a364f70>
square 裡存的是 lambda
為什麼不是印出 0, 1, 16 ?
square = []
for i in range(5):
square.append(lambda : i**2)
print(i) #4
print(square[0]()) #16
print(square[1]()) #16
在迴圈結束後執行,i = 4
所以 lambda 裡的 i = 4,會回傳 4**2
為什麼不是印出 0, 1, 16 ?
square = []
for i in range(5):
square.append(lambda : i**2)
print(square[i]()) #0 1 4 9 16
print(square[0]()) #0 1 4 9 16
如果在迴圈裡執行,會印出正確的結果
square = []
for i in range(5):
square.append(lambda x=i: x**2)
print(square[0]()) #0
print(square[1]()) #1
print(square[4]()) #16
如果在迴圈裡執行,會印出正確的結果
如果想要在迴圈外執行,可以將參數設為另一個變數
a = [1, 2, 3, 4, 5, 6]
b = map(lambda i: i+1, a)
print(b) #<map object at 0x7f7a81b87130>
print(list(b)) #[2, 3, 4, 5, 6, 7]
map( function, iterable object )
map 會根據特定函式對指定的序列做映射
意思就是依據函式去改變後面序列的內容
a = [1, 2, 3, 4, 5, 6]
b = filter(lambda i: i>3, a)
print(list(b)) #[4, 5, 6]
filter( function, iterable object )
filter 會根據特定函式對指定的序列做過濾
意思就是依據函式去過濾後面序列的內容,將回傳為 True 的項目留下
def a(func):
print("a")
return func
def b():
print("b")
c = a(b) #a
print(c) #<function b at 0x7f7eebe74dc0>
c() #b
函數可以當作參數傳遞並執行
def a(func):
print("a")
return func
#裝飾 b
@a
def b():
print("b")
b()
#a
#b
用語法糖包裝來簡化
def a1(func):
print(1)
return func
def a2(func):
print(2)
return func
def a3(func):
print(3)
return func
@a1
@a2
@a3
def b():
print("go!!!")
b()
用語法糖包裝來簡化
可以建立一個自訂的型態
class class_name():
a = 123
def f():
...
class_name.a
class_name.f()
依附於類別的變數,用 __init__ 來定義
class person():
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
id = 1 #也可以這樣設定
a = person("poemro", "F", 18)
print(a.name, a.gender, a.age)
#poemro F 18
也可以用關鍵字參數
class person():
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
id = 1
a = person(name="pomero", age=18, gender="F")
print(a.name, a.gender, a.age)
#poemro F 18
可以在 class 定義函式
class person():
def __init__(self, name, money, weight):
self.name = name
self.money = money
self.weight = weight
id = 1
def eat(self):
self.money -= 100
self.weight += 5
p = person("Hey", 1000, 50)
p.eat()
print(p.money, p.weight) #900 55
可以用物件改物件
class person():
def __init__(self, name, money, weight):
self.name = name
self.money = money
self.weight = weight
class rest():
def food(self, guest):
guest.money -= 100
guest.weight += 5
p = person("Hey", 1000, 50)
r = rest()
r.food(p)
print(p.money, p.weight) #900 55
如果從外部定義了和類別屬性名稱相同的屬性,就會被覆寫
class person():
def __init__(self, name, money, weight):
self.name = name
self.money = money
self.weight = weight
def say(self, text):
print(f"Hi, {text}")
p = person("Hey", 1000, 50)
p.say("hey") #Hi, hey
p.say = "???"
print(p.say) #???
用 getter 去讀取私有成員
用 setter 去修改私有成員
class person():
def __init__(self, name, money, weight):
self.name = name
self.money = money
self.weight = weight
def get_salary(self):
return self.__salary
def set_salary(self, new_salary):
self.__salary = new_salary
__salary = 30000
p = person("Hey", 1000, 50)
print(p.get_salary()) #30000
p.set_salary(28000)
print(p.get_salary()) #28000
繼承 ( inheritance ) 可以延續利用父類別的特性並加以修改
class person():
def __init__(self, name, money, weight):
self.name = name
self.money = money
self.weight = weight
class student(person): #student 繼承 person
id = 1 #新增 id
def eat(self, m):
self.money -= m
self.weight += m #可以使用 person 的屬性
s = student("Hey", 1000, 50)
print(s.id) #1
s.eat(10)
print(s.money, s.weight) #990 60
可以繼承父類別的方法
class person():
def __init__(self, name, money, weight):
self.name = name
self.money = money
self.weight = weight
class student(person):
def __init__(self, name, money, weight, id):
super().__init__(name, money, weight)
#繼承 parent 的 __init__
self.id = id
s = student("Hey", 1000, 50, 1)
print(s.name, s.id) #Hey 1
class meat():
def __init__(self, source, doneness, kg):
self.source = source
self.doneness = doneness
self.kg = kg
def cook(self, time):
if time < self.doneness:
print("Time is too short.")
class bread():
def __init__(self, kind):
self.kind = kind
class burger(meat, bread): #繼承 meat 跟 bread
def __init__(self, source, doneness, kg, kind):
meat.__init__(self, source, doneness, kg)
bread.__init__(self, kind)
b = burger("USA", 7, 10, "rye")
b.cook(6) #Time is too short.
When an error occurs, or exception as we call it, Python will normally stop and generate an error message.
These exceptions can be handled using the
try
statement.
try: #如果 print(x) 可以執行
print(x)
except: #如果 print(x) 會有錯誤
print("Something wrong")
#Something wrong
print(x) #NameError: name 'x' is not defined
如果直接執行 print(x)
使用例外處理,讓程式能繼續運行
except 的錯誤訊息
錯誤訊息 | 說明 |
---|---|
NameError | 使用沒有被定義的對象 |
IndexError | 索引值超過了序列的大小 |
TypeError | 數據類型 ( type ) 錯誤 |
SyntaxError | 語法規則錯誤 |
ValueError | 傳入值錯誤 |
KeyboardInterrupt | 當程式被手動強制中止 |
AssertionError | 程式 asset 後面的條件不成立 |
KeyError | 鍵發生錯誤 |
ZeroDivisionError | 除以 0 |
AttributeError | 使用不存在的屬性 |
IndentationError | 語法錯誤 ( 沒有對齊 ) |
IOError | Input/output異常 |
UnboundLocalError | 區域變數和全域變數發生重複或錯誤 |
try:
print(a)
except IndexError:
print("IndexError")
except NameError:
print("NameError")
#NameError
在 except 後放錯誤型別
try:
print(a)
except IndexError:
print("IndexError")
except Exception as e:
print(e)
#name 'a' is not defined
except Exception as 變數
可以印出全部的錯誤訊息
try:
print(a)
except:
pass
print("hello")
#hello
使用 pass 略過
a = input("Input: ")
try:
a = int(a)
print(a)
except:
print("Error")
else:
print("No error")
如果沒有錯誤,會執行 else
a = input("Input: ")
try:
a = int(a)
print(a)
except:
print("Error")
else:
print("No error")
finally:
print("Always print this")
不管有沒有錯誤,都會執行 finally
a = input("Input: ")
print(a)
if not type(a) is int:
raise TypeError("Only interger are allowed.")
print(f"{a} is int")
可以用 raise 強制中斷程式或拋出錯誤訊息
try:
a = int(input('Input 0~9:'))
assert a <= 9, f"{a} is not in range"
print(a)
except AssertionError as msg:
print(msg)
except:
print('sth wrong')
print('Continue')
assert 條件, 訊息
當條件為 False 時會執行
包含 Python 程式碼的檔案,可以引入
import math #引入叫 math 的模組
print(math.floor(123.2)) #使用 math 裡的函式 floor
import 模組名稱
import datetime
print(datetime.date.today()) #2024-10-27
from 模組名稱 import 方法
from datetime import date
print(date.today()) #2024-10-27
只匯入模組中的某一段程式
import 模組名稱 as 別名
import datetime as dd
print(dd.date.today()) #2024-10-27
將模組賦予別名
可以 import 自己寫的 .py 檔案
.
└── module
├── main.py
└── module.py
#module.py
def square(a, b):
return a ** b
s = "String from hello"
class stu():
def __init__(self, name, age):
self.name = name
self.age = age
def infor(self):
return f"My name is {self.name}, I'm {self.age} years old."
#main.py
from module import square, s, stu
print(square(2, 4))
print(s)
stu1 = stu("pomero", 16)
print(stu1.infor())
印出來的結果: