###### 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)
```