Python 基礎語法教學
軟體開發Python 是公認的語法精簡且容易上手的程式語言,但也因為其精簡的特性,很多語法跟其他程式語言差異很大,不常使用的話也會很容易忘記。 因此,我決定為自己製作這篇速查文章,目的是為了迅速回顧和瞭解 Python 的特性和語法。 如果您跟我一樣,同時撰寫很多不同的程式語言,相信這篇文章對您也會有所幫助。
在撰寫程式碼時,查詢官方文檔是一個良好的習慣,以下是 Python 官方的說明文件:
註解
# 我是單行註解
'''
我是多行註解
我是多行註解
我是多行註解
'''
"""
我是多行註解
我是多行註解
我是多行註解
"""
輸入/輸出
# 執行後,終端機就會要求使用者輸入資料
# 使用者輸入的資料就會儲存在 str 變數中
str = input("請輸入資料: ")
# 輸出
print(項目1[,項目2,...,] sep=分隔符號, end=結束符號)
print(100, 50, 10, sep="&") # 輸出 100&50&10
print(100, end="") # 輸出 100,且之後輸出不會換行
使用變數
保留字
False | None | True | and | as |
assert | async | await | break | class |
continue | def | del | elif | else |
except | finally | for | from | global |
if | import | in | is | lambda |
nonlocal | not | or | pass | raise |
return | try | while | with | yield |
多重指定
# x, y, z 都是 10
x = y = z = 10
# x = 10
# y = 20
# z = 30
x, y, z = 10, 20, 30
刪除變數
# 刪除變數
del x
檢查型別
# 直接輸出型別資訊
print(type(x))
# 方法ㄧ: 判斷型別
if isinstance(x, str):
print('x is a string')
# 方法二: 判斷型別
if (type(x) == str):
print('x is a string')
數值
整數
# 整數
x = 100
# 底線會被忽略
x = 1_200_300
# 2 進位
x = 0b1101
print(x) # 輸出 13
print(bin(x)) # 輸出 0b1101
# 8 進位
x = 0o57
print(x) # 輸出 47
print(oct(x)) # 輸出 0o57
# 16 進位
x = 0x57
print(x) # 輸出 87
print(hex(x)) # 輸出 0x57
浮點數
x = 10.555
Python 的浮點數存在精度不準確問題,但這也非 Python 獨有,觀察下方例子,照理說應該要輸出 0.3,可是實際上卻會輸出 0.2999999999999998。 不過這一點點的誤差,在大部分應用中都不會造成問題,但如果您的應用要求高精度的話,那麼可以改用 decimal.Decimal。
# 執行後會輸出 0.2999999999999998
print(3 - 2.7)
# 使用 Decimal
from decimal import Decimal, getcontext
getcontext().prec = 6 # 指定精度
print(Decimal(3) - Decimal(2.7)) # 輸出 0.300000
科學記號
# 以下表示為 10 的 3 次方,也就是 1000
x = 1e+3
# 以下表示為 10 的 -3 次方,也就是 0.001
x = 1e-3
# 以上 e 大小寫都可以
常用函數
abs(x) # 取得絕對值
divmod(x, y) # 取得 x 除以 y 的商數和餘數
pow(x, y) # x 的 y 次方,等於 x ** y
pow(x, y, z) # 等於 (x ** y) % z
# 四捨五入
round(x, n) # 四捨五入至第 n 位
round(123.45678) # 等於 123
round(123.45678, 2) # 等於 123.46
# 無條件進位
math.ceil(123.45678) # 等於 124
math.ceil(123.45678 * 10) / 10.0 # 等於 123.5
math.ceil(123.45678 * 100) / 100.0 # 等於 123.46
# 無條件捨去
math.floor(123.45678) # 等於 123
math.floor(123.45678 * 10) / 10.0 # 等於 123.4
math.floor(123.45678 * 100) / 100.0 # 等於 123.45
布林值
flag = True
flag = False
字串
# 單行字串
str = "這是字串"
str = '這是字串'
# 多行字串
str = """這是字串
這是字串
這是字串"""
str = '''這是字串
這是字串
這是字串'''
索引值
# 字串索引值
str = "Hello"
print(str[0]) # 輸出 H
print(str[1]) # 輸出 e
print(str[-1]) # 輸出 o
print(str[-2]) # 輸出 l
格式化字串
百分比(%)
# %s 字串
# %d 整數
# %f 浮點數 (預設保留小數 6 位)
# %.2f 浮點數 (保留小數 2 位)
# 輸出 string_100_3.140000
print('%s_%d_%f' % ('string', 100, 3.14))
str.format()
# 輸出 My name is Mark and my age is 30
print('My name is {} and my age is {}'.format('Mark', 30))
# 指定順序
# 輸出 My name is 30 and my age is Mark
print('My name is {1} and my age is {0}'.format('Mark', 30))
# 結合 List
# 輸出 My name is Andy
print('My name is {name[1]}'.format(name=['Mark', 'Andy', 'Terry']))
# 結合 Dict
# Dict 前面要加 **
# 輸出 My name is Mark and my age is 30
print('My name is {name} and my age is {age}'.format(**{'name': 'Mark', 'age': 30}))
# 分開字串
# 輸出 1 2 3 4 5 6
print('{} {} {} {} {} {}'.format(*'123456'))
f-string
# 可放變數
# 輸出 My name is Mark and my age is 30
name = 'Mark'
age = 30
print(f'My name is {name} and my age is {age}')
# 可放函數
# 輸出 2^3 = 8.0
import math
print(f'2^3 = {math.pow(2, 3)}')
字串前 f、r、b、u
- f
- 格式化字串
- r
- 後面字串為普通字串,\n 之類的跳脫字元會直接輸出。
- b
- 後面字串為 bytes 類型
- u
- 後面字串以 Unicode 編碼
常用函數
s.capitalize() # 首字大寫
s.lower() # 全部字串轉小寫
s.upper() # 全部字串轉大寫
s.replace(old, new[, max]) # 字串取代
s.split(str="", num=-1) # 字串分割,轉成 List
s.zfill(width) # 返回指定長度字串,字串長度不足的話,往左邊補 0
串列 (list)
# 就是陣列
list1 = ['a', 'b', 'c', 1000, 2000]
# 生成式
# list1 = [0, 1, 2, 3, 4]
list1 = list(x for x in range(5))
# 尋訪方式ㄧ: value
for val in list1:
print(val)
# 尋訪方式二: key + value
for key, val in enumerate(list1):
print(f"{key} = {val}")
常用函數
len(list) # 取得串列長度
list(seq) # 將序列(list、tuple)轉換為串列
list.append(obj) # 將 obj 加入串列末端
list.extend(seq) # 將序列(list、tuple)中的元素加入串列末端
list.index(obj) # 返回 obj 在串列中的索引值
list.insert(index, obj) # 在指定 index 位置插入 obj
list.pop([index=-1]) # 移除並返回指定 index 元素,預設為最後一個元素
list.remove(obj) # 移除串列中第一個匹配 obj 的元素
list.reverse() # 串列反向排序
元组 (Tuple)
與串列類似,但元組建立後不能修改。
tup1 = ('a', 'b', 'c', 1000, 2000)
# 如果只有一個元素,需要加,
tup1 = ('a',)
# 元組不能修改,以下程式碼會出錯
tup1[4] = tup1[4] + 1
# 尋訪方式ㄧ: value
for val in tup1:
print(val)
# 尋訪方式二: key + value
for key, val in enumerate(tup1):
print(f"{key} = {val}")
常用函數
len(tup) # 取得元组長度
tuple(seq) # 將序列(list、tuple)轉換為元组
集合 (Set)
集合有以下特性:
- 只有可雜湊 (hashable) 的資料可以加入集合。
- 集合內不會有重複的資料。
- 集合是無序資料。
set1 = {"a", "b", "c"}
# 尋訪方式ㄧ: value
for val in set1:
print(val)
# 尋訪方式二: key + value
for key, val in enumerate(set1):
print(f"{key} = {val}")
常用函數
len(set) # 取得集合長度
set(obj) # 建立集合,obj 可以是 string、List、Tuple 及 Dict
set.add(obj) # 將 obj 加入集合
set.copy() # 複製集合 (淺複製)
set.remove(obj) # 移除集合中 obj 元素,obj 不存在將產生 KeyError
set.discard(obj) # 移除集合中 obj 元素,obj 不存在不會出錯
set.pop() # 移除第一個元素元素,預設為最後一個元素
set.clear(]) # 清空集合
字典 (Dict)
dict1 = {'key1': 1, 'key2': 2, 'key3': 3}
# 生成式
# dict1 = {'h': 1, 'e': 1, 'l': 2, 'o': 1}
str1 = 'hello'
dict1 = {i: str1.count(i) for i in str1}
# 尋訪方式ㄧ: key
for key in dict1:
print(key)
# 尋訪方式二: key
for key in dict1.keys():
print(key)
# 尋訪方式三: value
for val in dict1.values():
print(val)
# 尋訪方式四: key + value
for key, val in dict1.items():
print(f"{key} = {val}")
常用函數
# 常用函數
len(dict) # 取得字典長度
dict.clear() # 清空字典
dict.copy() # 複製字典 (淺複製)
dict.fromkeys(seq[, val]) # 建立字典,以序列 seq 為 key 值,val 為所有 key 對應的初始值
dict.get(key, default=None) # 返回指定 key 對應的值,如果不存在返回 default 值
dict.items() # 以列表返回 (key, value) 元組,常用於字典尋訪
dict.keys() # 返回字典所有的 key 值
dict.values() # 返回字典所有的 value 值
# 深複製 (deep copy)
import copy
dict2 = copy.deepcopy(dict1)
運算子
算術運算子
運算子 | 說明 | 運算子 | 說明 |
---|---|---|---|
+ | 加法運算 | % | 取餘數 |
- | 減法運算 | // | 取整除商數 |
* | 乘法運算 | ** | 次方,例如 2**3,表示 2 的 3 次方 |
/ | 除法運算 |
比較運算子
運算子 | 說明 | 運算子 | 說明 |
---|---|---|---|
< | 小於 | > | 大於 |
<= | 大於或等於 | >= | 小於或等於 |
== | 等於 | != | 不等於 |
邏輯運算子
運算子 | 說明 | 運算子 | 說明 |
---|---|---|---|
and | 並且 | or | 或者 |
not | 不 |
成員運算子
運算子 | 說明 | 運算子 | 說明 |
---|---|---|---|
in | 指定值在 List 中 | not in | 指定值不在 List 中 |
# 以下為 True
3 in [1, 2, 3]
# 以下為 False
4 in [1, 2, 3]
三元運算子
# 範例: 當 a 大於 10 時,a 就等於 10,否則 a 等於 0。
a = 10 if a > 10 else 0
程式流程控制
判斷式
# if 判斷式
if animal == 'dog':
print('dog')
elif animal == 'cat':
print('cat')
else:
print('unknown')
# if 新功能 (Python 3.8 之後)
if x := expression
pass
// switch 判斷式
match animal:
case "dog":
print('dog')
case "cat":
print('cat')
case _:
print('unknown')
迴圈
# for 迴圈
# range(start, end, step)
for i in range(5):
print(i, end="") # 輸出 01234
for i in range(5, 10):
print(i, end="") # 輸出 56789
for i in range(0, 10, 2):
print(i, end="") # 輸出 02468
# while 迴圈
i = 0
while i < 10:
i += 1
# while 迴圈 + else
# 當 while 後面的條件為 False 時,執行 else 區塊
i = 0
while i < 10:
i += 1
else:
print('結束')
迴圈中可以使用以下語句:
break: 跳出迴圈。
continue: 結束此次迴圈,繼續下一次迴圈。
pass: 用於保持程式結構完整性,沒有任何功用。
例外處理
try:
# 拋出異常
raise Exception()
except Exception: # 單一例外寫法
pass
except (IOError, OSError): # 多個例外寫法
pass
else:
print('沒有觸發異常才會執行')
finally:
print('無論有無觸發異常都會執行')
函數
# 基本使用
def outputStr(str1, str2):
print(str1 + '_' + str2)
outputStr('A', 'B')
# 關鍵字參數
def outputStr(str1, str2):
print(str1 + '_' + str2)
outputStr(str2 = 'B', str1 = 'A')
# 預設參數
def outputStr(str1, str2 = 'B'):
print(str1 + '_' + str2)
outputStr('A')
# 不定長度參數
def outputStr(*args):
pass
outputStr() # args = ()
outputStr(1) # args = (1,)
outputStr(1, 2) # args = (1, 2)
# 不定長度參數 + 必填參數
def outputStr(num, *args):
pass
outputStr() # 程式出錯,因為 str1 為必要參數
outputStr(1) # num = 1, args = ()
outputStr(1, 2) # num = 1, args = (2,)
# 回傳 (使用 return)
def add(num1, num2):
return num1 + num2
print(add(1, 2)) # 回傳 3
# 回傳多筆資料 (使用 return)
def test():
return 1, 2, "a", "b"
print(test()) # 回傳 (1, 2, 'a', 'b')
# 函數回傳註解
# -> int 僅僅只是註解而已,就算回傳字串也不會出錯,只是提示開發人員該函數回傳 int。
def add(num1, num2) -> int:
return num1 + num2
匿名函数 (lambda)
# 具名函數
def add(num1, num2):
return num1 + num2
print(add(1, 2))
# 匿名函数
sum = lambda num1, num2: num1 + num2
print(sum(1, 2))
# 也可以直接這樣使用
print((lambda num1, num2: num1 + num2)(1, 2))
類別
與 Java 相比,Python 的類別不支援 interface 和 protected 修飾詞,但允許多重繼承。
# 無繼承
class Math:
def __init__(self):
pass
# 繼承單一類別
class Math(object):
def __init__(self):
pass
# 繼承多個類別
class Math(object, object2):
def __init__(self):
pass
Python 類別的基本結構如下:
# Math 類別繼承 object
class Math(object):
# 靜態變數
PI = 3.14
# 建構函數
def __init__(self):
super().__init__() # 呼叫父類別建構函數
self.a = 1 # 實例變數 (公開)
self.__b = 2 # 實例變數 (私有)
self.func1() # 呼叫類別函數
# 實例函數 (公開)
def func1(self):
pass
# 實例函數 (私有)
def __func2(self):
pass
# 靜態函數
@staticmethod
def func3():
pass
# 使用類別
math = Math()
math.func1()
模組 (Module)
本節使用以下目錄結構進行說明。
# 目錄結構
# package
# |_ module_1.py
# |_ class_1.py
# test.py
# module.py 內容
def test1():
print('module_1 > test1()')
def test2():
print('module_1 > test2()')
# class_1.py 內容
class Class1:
def __init__(self):
pass
def info(self):
print('Class1.info()')
在 test.py 程式中使用模塊。
# 引入函數
# 引入全部函數 from package.module_1 import *
# 引入單一函數 from package.module_1 import test1
from package.module_1 import *
test1()
test2()
# 引入類別
from package.class_1 import Class1
class_test = Class1()
class_test.info()
使用 __init__.py 檔
__init__.py 檔,是用來宣告這個資料夾為一個模組,檔案可以完全沒有內容,但也可以用來簡化 import 語句。 在 package 目錄中加入 __init__.py 檔,並填入以下內容。
# 在 __init__.py 寫入以下內容
from package.module_1 import test1
from package.module_1 import test2
from package.class_1 import Class1
# 在 test.py 程式中使用模塊
from package import *
test1()
test2()
class_test = Class1()
class_test.info()
切片運算
切片運算可用於 string、List 及 Tuple,以下使用字串說明
# 格式:seq[start]
# 格式:seq[start, end]
# 格式:seq[start, end, step]
str = "Hello"
print(str[0:3]) # 輸出 Hel,索引值從 0 ~ 2,不包含 3
print(str[1:4]) # 輸出 ell,索引值從 1 ~ 3,不包含 4
print(str[:3]) # 輸出 Hel,等於 str[0:3],第 1 個索引值沒寫表示 0
print(str[3:]) # 輸出 lo,等於 str[3:5],第 2 個索引值沒寫表示最後一個索引值
print(str[:]) # 輸出 Hello,等於 str[0:5]
print(str[0:4:2]) # 輸出 Hl
print(str[0:5:2]) # 輸出 Hlo
單一敘述多行撰寫
有時候可能一行程式碼非常的長,我們可以使用斜線 (\) 多行撰寫。
# 原程式碼
x = a + b + c + d + e
# 多行撰寫程式碼
x = a \
+ b \
+ c \
+ d \
+ e
0 則留言