註釋: #
單行註釋 """
多行註釋 """
print (" ")
輸出函數
基本運運算元: +
-
*
/
//
(取整) %
(取餘) **
(冪運算)
變數的定義: 變數名 = 值
(每個變數使用前都必須賦值,變數在賦值以後才會被創造,定義時不需要指定變數型別)
type( )
檢視變數型別函數
input( )
變數輸入函數 用法舉例: a = input(「輸入數位:」) 輸入的任何內容的資料型別預設為字元型str
int(a)
float(b)
型別轉換函數,將a轉換為int型,將b轉換為float型
格式化輸出:
print("格式化字串" % 變數1)
print("格式化字串" % (變數1,變數2...))
(%s - 字串)
(%d - 帶符號十進位制整數——%06d表示輸出六位數,不足地方用0補全)
(%f - 浮點數——%.02f表示小數點後顯示兩位)
(%% - 輸出%)
f-格式化字串: print(f’ My name is {name} ')
跳脫字元: \n
換行 \t
製表符 : 1個tab鍵(4個空格)
結束符:python中的 print 預設以 \n
為結束符,即預設換行,但可自己設定,如: print('hello', end="\t")
識別符號 由字母、數位、下劃線組成,不能以數位開頭,不能與關鍵詞重名。識別符號區分大小寫,命名規則推薦多個單詞時全部小寫並將每個單詞用下劃線隔開。
if語句: 在Python開發中,Tab和空格一定不能混用!
if 條件1:
條件1成立時要執行的程式碼
elif 條件2:
條件2成立時要執行的程式碼
else:
條件1、2都不成立時執行的程式碼
if語句訓練:猜拳遊戲
#if-elif-else訓練: 猜拳遊戲
import random
player = int(input('請出拳 (0-拳頭 1-剪刀 2-布):'))
computer = random.randint(0,2)
#平局
if player == computer:
print('平局')
#電腦勝
elif ( ((player == 0) and (computer == 2)) or ((player == 1)and(computer == 0)) or ((player == 2)and(computer == 1)) ):
print('電腦贏了!你個睿智!你連電腦都打不過!')
#玩家勝
else:
print('你贏了!不容易不容易啊!')
亂數的實現:
匯入 random
模組,使用 randint
(隨機整數) 功 如:
import random
num = random.randint(0,2)
(num為0、1、2中的隨機一個數)
三目運運算元:
條件成立時的表示式 if 條件 else 條件不成立時的表示式
如: MaxNum = a if a>b else b
While 迴圈:
while 條件:
條件成立時重複執行的程式碼
注意: 計數的初始值習慣寫為0
break 和 continue :
break
為終止迴圈,即不再回圈
continue
為退出當前一次迴圈而直接執行下一次迴圈,即跳入下一次迴圈
for 迴圈:
for 臨時變數 in 序列:
重複執行的程式碼
while 與 else : 如果迴圈由 break 停止,則else下的程式碼不執行,for 與 else 的用法與此類似
while 條件:
條件成立時重複執行的程式碼
else:
迴圈正常結束之後執行的程式碼
字串可以用單引號、雙引號、三引號括起來,字串為不可變型別。
python中每個字串自帶下標和索引,可用 str[x]
來精確存取字串 str 中的某個字元
切片: 指對 字串、列表、元組 進行擷取其中一部分的操作
語法: 序列[開始位置下標 : 結束位置下標 : 步長]
其中切片不包含結束位置下標對應的資料 ,即開始位置下標和結束位置下標為 [ ) 的包含形式
下標 和 步長 均可不寫或寫負數,步長預設為1,若下標開始到結束的方向與步長的方向衝突,則無法選取出資料
字串的查詢: find() 、index() 、count() 、rfind() 、rindex()
find()
: 檢測某個子串是否包含在這個字串中,如果存在則返回這個子串開始位置的下標,否則返回-1
字串序列.find( 子串 , 開始位置下標 , 結束位置下標 )
開始和結束位置下標可以省略,表示在整個字串序列中查詢
index()
: 與find()函數的用法一樣,但如果不存在要查詢的子串,則會報錯
count()
:返回某子串在該字串中出現的次數,若不存在則返回0
rfind()
與 rindex()
查詢方向為從右側開始,其功能與 find() 與 index() 相同
字串的替換 :replace() 替換
字串序列.replace ( 舊子串、新子串、替換次數 )
注意: replace函數並不會改變原有字串的資料,修改後的資料是replace函數的返回值
字串的分割: split() 分割,返回一個列表,丟失分割字元
字串序列.split(分割字元,分割次數)
注意:split函數也不會改變原有字串資料,修改後的資料為函數返回值
列表的合併:join() 合併,返回一個字串,新增連線字元
連線字串.join(多字串組成的列表)
注意: join() 合併 是 split() 分割 的逆序操作
字串修改大小寫函數:
capitalize()
將字串第一個字母轉換為大寫,其餘均為小寫
title()
將字串中每個單詞的首字母轉化成大寫,其餘均為小寫
lower()
將字串中的大寫全部轉換為小寫
upper()
將字串中的小寫全部轉換為大寫
例:
initial: brotheR aNd me
capitalize: Brother and me
title: Brother And Me
lower: brother and me
upper: BROTHER AND ME
字串刪除空白字元函數:
lstrip()
: 刪除字串左側空白字元
rstrip()
: 刪除字串右側空白字元
strip()
: 刪除字串兩側空白字元
例:
initial: " brother and me "
lstrip: 「brother and me "
rstrip: " brother and me」
strip: 「brother and me」
字串對齊函數: ljust() 、 rjust() 、center()
返回 一個原字串 左/右/中 對齊,並用指定字元(預設空格)填充至對應長度的新字串
字串序列.ljust( 長度 , 填充字元 )
字串序列.rjust( 長度 , 填充字元 )
字串序列.center( 長度 , 填充字元 )
例:
initial: brother and me
ljust: brother and me----------------
rjust: ----------------brother and me
center: --------brother and me--------
字串判斷開頭或結尾函數:
startswith()
: 檢查字串是否以指定子串開頭,是則返回True,否則返回False。如果設定開始和結束位置下標,則在指定範圍內檢查
字串序列.startswith(子串,開始位置下標,結束位置下標)
endswith()
: 檢查字串是否以指定子串結尾,用法與 startswith()相同
字串序列.endswith(子串,開始位置下標,結束位置下標)
字串字元型別判斷函數:
isalpha()
: 如果字串非空且只包含字母則返回True , 否則返回False
isdigit()
: 如果字串非空且只包含數位則返回True , 否則返回False
isalnum()
: 如果字串非空且只包含數位或字母則返回True, 否則返回False
isspace()
: 如果字串非空且只包含空格則返回True , 否則返回False
列表 : 可以用下標選取指定資料,列表為可變型別。
列表資料查詢函數:
index()
: 返回指定資料所在位置的下標,若資料不存在則報錯
列表序列.index(資料, 開始位置下標, 結束位置下標)
count()
: 返回指定資料在該列表出現的次數,若資料不存在則返回0
列表序列.count(資料)
len()
: 返回列表的長度,即列表中資料的個數
len(列表序列)
判斷列表中是否存在指定資料:
in
: 判斷指定資料在某個序列的存在,存在返回True,否則返回False
'指定資料' in 列表序列
not in
: 與 in 的用法相同,返回結果相反
列表資料增加函數:
append()
: 列表結尾追加資料,若資料為一個序列,則直接追加整個序列到列表的結尾位置
列表序列.append(資料)
extend()
: 列表結尾追加資料,若資料為一個序列,則將序列的資料逐一新增到列表,若資料為字串,則將單獨的每個字元逐一新增到列表
列表序列.extend(資料)
insert()
: 指定位置新增資料,增添方式與 append() 相同
列表序列.insert(位置下表,資料)
列表資料刪除函數:
del 目標(列表名 或 列表指定下標資料)
pop()
: 刪除指定下標的資料(預設為最後一個),並返回該資料。
列表序列.pop(下標)
remove()
: 移除列表中某個資料的第一個匹配項,若匹配失敗則報錯
列表序列.remove(資料)
clear()
: 清空列表中的所有資料
列表序列.clear()
列表資料修改函數:
修改指定下標資料: 列表序列[下標] = 資料
reverse()
: 將列表資料的順序逆置
列表序列.reverse()
sort()
: 對列表的資料進行排序
列表序列.sort( key = None, reverse = False)
注意: reverse = True 降序 reverse = False 升序(預設)
列表資料複製函數:
copy()
: 列表資料複製
新列表序列 = 原列表序列.copy()
即將原列表的資料複製到新列表中
列表的迴圈遍歷:
while迴圈方法 :
i = 0
while i < len(list):
print(list[i])
i += 1
for迴圈方法 :
for i in list:
print(i)
列表巢狀:指一個列表裡包含了其他的子列表。
例: List = [ ['a' , 'b' , 'c'] , ['1' , '2' , '3'] , ['&' , '$' , '%'] ]
列表綜合訓練:
#將8位元老師隨機分配到3個辦公室中
import random
teacher = ['a1','a2','a3','a4','a5','a6','a7','a8']
room = [[],[],[]]
for i in teacher:
n = random.randint(0,2)
room[n].append(i)
print(room)
i = 1
for r in room:
print(f'辦公室{i}的人數是{len(r)},他們分別為:',end = '\t')
for name in r:
print(name,end = '\t')
print()
i += 1
元組: 一個元組可以儲存多個資料(與列表相同),但元組內的資料是不能修改的。
元組名 (資料1 , 資料2 , 資料3)
注意: 如果定義的元組只有一個資料,那麼需要新增逗號,湊則資料型別為該資料型別,而不是 元組(tuple) 資料型別,如 tuple = (‘x’ , )
元組的常見操作:
按下標查詢資料 : 如tuple1[0] 、 tuple1[1]等
index()
: 查詢某個資料,用法與字串、列表的index相同
count()
: 統計某個資料在當前元組出現的次數
len()
: 統計元組中的資料個數
元組資料的修改:
元組內的直接資料如果修改則立即報錯
如果元組裡面有列表,可直接修改列表內的資料,如 (‘abc’ , ‘qwe’ , [‘123’ , ‘456’ , ‘789’] , ‘jkl’) 元組就可以修改其中的 ‘123’ , ‘456’ , ‘789’ 資料
字典:字典裡的資料是以鍵值對形式儲存的。字典為可變型別。
特點: 符號為大括號,資料為鍵值對形式出現,各個鍵值對之間用逗號隔開。
dict1 = { '鍵1' : '值1' , '鍵2' : '值2' , '鍵3' : '值3' }
空字典除了可以用空大括號建立,也可以用函數建立: dict2 = dict()
字典常見操作:
增 / 改: 字典序列[‘key’] = 值
注意: 如果key存在則修改該鍵對應的值,如果key不存在則新增此鍵值對
刪:
del(dict)
刪除字典
del dict['Key']
刪除字典中指定鍵值對
dict.clear()
清空字典
查:
按key值寫法直接查詢: 字典序列[‘鍵’]
按函數寫法查詢: get() keys() values() items()
get()
: 獲取某個鍵對應的值
字典序列.get(key , 預設值)
注意:若當前查詢的key不存在則返回預設值,若預設值省略不寫則返回None
keys()
: 獲取字典中所有的key,並返回可迭代物件
字典序列.keys()
values()
: 獲取字典中所有的values,並返回可迭代物件
字典序列.values()
items()
: 獲取字典中所有的鍵值對(key 和 values),並返回可迭代物件 ,裡面的資料是元組
字典序列.items()
字典的迴圈遍歷:
遍歷字典的Key:
for key in dict1.keys():
print(key)
遍歷字典的Value:
for value in dict1.values():
print(value)
遍歷字典的元素:
for item in dict1.items():
print(item)
遍歷字典的鍵值對(拆包):
for key, value in dict1.items():
print(f'{key} = {value}')
集合: 建立集合可使用 {} 或 set() ,但是如果要建立空集合只能使用 set() , 因為使用 {} 會建立空字典。
集合資料特點: 集合裡面的資料會自動去重,不允許重複;集合裡面的資料沒有順序,且不支援下標。集合是可變型別。
集合的建立:
直接建立: s1 = {10 , 20 , 30 , 40 , 50}
使用set()建立: s2 = set('brother')
建立空集合: s3 = set()
集合中資料的常見操作:
增加資料: add() update()
集合.add(資料)
增加單個資料,要增加的資料在原集合中存在的話,不進行任何操作
集合.update(資料列表)
在集合中增加資料序列
刪除資料: remove() discard() pop()
集合.remove(資料)
刪除集合中的指定資料,如果資料不存在則會報錯
集合.discard(資料)
刪除集合中的指定資料,如果資料不存在也不會報錯
集合.pop()
隨即刪除集合中的某個資料,並返回這個資料
查詢資料: in 判斷資料在集合序列 not in 判斷資料不在集合序列
公共操作:運運算元、公共方法、容器型別轉換
運運算元:
+
合併,支援字串、列表、元組
*
複製,支援字串、列表、元組
in
元素是否存在,支援字串、列表、元組、字典
not in
元素是否不存在,支援字串、列表、元組、字典
公共方法:
len()
計算容器中元素個數
del()
刪除元素
max()
返回容器中元素的最大值
min()
返回容器中元素的最小值
range(start,end,step)
生成從start到end的數位(其中不包含end數位),步長為step,供for迴圈使用
enumerate()
將一個可遍歷的資料物件(列表、元組或字串)組合為一個索引序列,同時列出資料和資料下標,一般用在for迴圈中
enumerate(可遍歷物件, start=0)
容器型別轉換:
tuple(序列)
: 將某個序列轉換成元組
list(序列)
: 將某個序列轉換成列表
set(序列)
: 將某個序列轉換成集合
推導式(生成式): 列表推導式、字典推導式、集合推導式
作用: 化簡程式碼
列表推導式:用一個表示式建立一個有規律的列表或控制一個有規律列表。
建立0-10的列表:
list = [i for i in range(10)]
建立0-10的偶數列表:
list = [i for i in range(10) if i % 2 == 0]
多個for迴圈列表:
list = [(i , j) for i in range(3) for j in range(3)]
字典推導式:快速合併列表為字典或提取字典中目標資料
賦值體驗:
dict = {i:i*2 for i in range(1,5)}
將兩個列表合併為字典:
list1 = ['name' , 'age' , 'gender']
list2 = ['Tom' , 20 , 'man']
dict = { list1[i] : list2[i] for i in range(len(list1)) }
提取字典中目標資料:
counts = {'a' : 150 , 'b' : 200 , 'c' : 250}
count = {key : value for key , value in counts.items() if value >= 200}
集合推導式:
list = [1,1,2]
set = {i * 2 for i in list}
函數:
def 函數名(引數):
「」" 說明檔案內容 「」"
程式碼1
程式碼2
…
注意:引數可有可無,必須先定義後使用
函數中return之後的程式碼並不會執行
help(函數名) 檢視函數解釋說明的資訊
函數(二):
區域性變數:只在函數體內部生效的變數
全域性變數:指在函數體內、外都能生效的變數
在函數體內部修改全域性變數:在函數體內部用 global 宣告變數為全域性變數後修改
函數有多個返回值時: return 後面可以直接書寫 元組、列表、字典,返回多個值
位置引數:呼叫函數時根據函數定義的引數位置來傳遞引數,傳遞和定義引數的順序及個數必須一致
關鍵字引數:函數呼叫時,通過「鍵=值」的形式加以指定傳參,關鍵字引數之間不存在先後順序
預設引數:也叫預設引數,用於在定義函數時為引數提供預設值,呼叫函數時可以不傳入有預設值的引數。在定義和呼叫函數時,位置引數必須在預設引數之前
不定長引數:也叫可變引數,用於不確定呼叫時會傳遞多少個引數的場景,可用 包裹位置引數 或 包裹關鍵字引數 來進行引數傳遞
包裹位置傳遞(元組):
def 函數名( *args ):
print( args )
函數名( 'abc' , 123 )
包裹關鍵字傳遞(字典):
def 函數名( **kwargs):
print( kwargs )
函數名( a = 'abc' , b = 123)
包裹位置傳遞和包裹關鍵字傳遞都是一個組包的過程,即收集零散資料並組成一個元組或字典
返回值拆包:
元組: return 10, 20 num1, num2 = 函數 即得到num1 = 10 , num2 = 20
字典: 對字典拆包,得到的是字典的key
交換變數值:
方法一:藉助第三變數儲存資料
方法二: a, b = b, a
參照: 在python中,值是靠參照來傳遞的
可以用 id() 來判斷兩個變數是否為同一個值的參照。可以將id理解為那塊記憶體的地址標識。
可變型別與不可變型別:
可變型別:列表(list)、字典(dict)、集合(set)
不可變型別:整型、浮點型、字串、元組
函數加強應用—學員管理系統:
#定義功能介面函數
def print_info():
"""函數功能介面"""
print('---select---')
print('1.add')
print('2.delete')
print('3.modify')
print('4.query')
print('5.show all')
print('6.exit')
print('----end----')
#定義列表等待儲存學員資訊
info = []
#新增學員資訊函數
def add_info():
"""學員新增函數"""
new_name = input('input name:')
new_id = input('input id:')
new_tel = input('input telephone:')
global info
for i in info:
if new_name == i['name']:
print('name exists!')
#return 退出當前函數,不執行下面新增資訊的程式碼
return
info_dict = {}
info_dict['name'] = new_name
info_dict['id'] = new_id
info_dict['tel'] = new_tel
info.append(info_dict)
print('add successful!')
#刪除學員資訊
def del_info():
"""學員刪除函數"""
del_name = input('input name:')
global info
for i in info:
if del_name == i['name']:
info.remove(i)
print('delete successful!')
break
else:
print('name does not exist!')
#修改學員資訊
def modify_info():
"""學員資訊修改函數"""
modify_name = input('input name:')
global info
for i in info:
if modify_name == i['name']:
i['tel'] = input('input new telephone:')
print('modify successful!')
break
else:
print('name does not exist!')
#查詢學員資訊
def search_info():
"""查詢資訊函數"""
search_name = input('input name:')
global info
for i in info:
if search_name == i['name']:
print('---Message---')
print(f"The name is {i['name']}, The id is {i['id']}, The telephone is {i['tel']}。")
break
else:
print('name does not exist!')
#展示所有學員資訊函數
def showall_info():
"""展示資訊函數"""
print('name\tid\ttelephone')
global info
for i in info:
print(f"{i['name']}\t{i['id']}\t{i['tel']}")
while True:
#1.顯示功能介面
print_info()
#2.使用者輸入功能序號
user_num = int(input('your choice:'))
#3.按照使用者輸入的功能序號,執行不同的功能(函數)
if user_num == 1:
add_info()
elif user_num == 2:
del_info()
elif user_num == 3:
modify_info()
elif user_num == 4:
search_info()
elif user_num == 5:
showall_info()
elif user_num == 6:
exit_flag = input('are you sure? Y/N')
if exit_flag == 'Y':
break
else:
print('Error!')
遞迴:
特點: 函數內部自己呼叫自己、必須有出口。
#遞迴函數求1~n的累加和
def num(n):
#出口
if n == 1:
return 1
#函數內部自己呼叫自己
return n+num(n-1)
若沒有出口,則報錯提示超出最大遞迴深度(996)。
lambda表示式(匿名函數)
:
應用場景: 化簡程式碼。如果一個函數只有一個返回值,並且只有一句程式碼,可以使用lambda簡化。
lambda 參數列: 表示式
lambda表示式的參數列可有可無,函數的引數在lambda表示式中完全適用。
lambda表示式能夠接收任何數量的引數但只能返回一個表示式的值。
#計算 a+b 的lambda實現
fn = lambda a,b: a+b
print(fn(1,2))
#輸出結果: 3
lambda的引數形式:無參、有參、預設引數(預設)、可變引數*args、可變引數**kwargs。
#無參
fn1 = lambda : 100
#有參
fn2 = lambda a: a
#預設引數
fn3 = lambda a,b,c=100: a+b+c
#可變引數 *args(元組)
fn4 = lambda *args: args
#可變引數 *kwargs(字典)
fn5 = lambda **kwargs: kwargs
lambda的應用:
#1.帶判斷的lambda
fn1 = lambda a,b: a if a>b else b #兩個數比大小
fn2 = lambda n: n+fn2(n-1) if n != 1 else 1 #遞迴求1~n的累加和
#2.列表資料按字典key的值排序
students = [
{'name':'Tom','age':19},
{'name':'Alice','age':20},
{'name':'Hack','age':18}
]
students.sort(key=lambda n: n['name']) #按照名字首字母升序排序
students.sort(key=lambda n: n['age'], reverse=True) #按照年齡降序排序
高階函數:
把函數作為引數傳入,這樣的函數稱為高階函數(即複合函數)。
測試用到的小函數:
abs():對數位求絕對值
round():對數位進行四捨五入
def sum(a, b, f):
return f(a)+f(b)
result1 = sum(3.14, -2.8, abs)
result2 = sum(3.14, -2.8, round)
#lambda表示式改寫
sum = lambda a,b,f: f(a)+f(b)
Python內建高階函數: map()、reduce()、filter()。
map(func, list)
:將傳入的函數變數func作用到列表變數list中的每個元素中,並將結果組成新的列表(python2)/迭代器(python3)返回。
#計算list1序列中各個數位的三次方
list1 = [1,2,3,4,5]
def func(x):
return x ** 3
result = map(func, list1) #此時result為map返回的迭代器
print(result) #將返回迭代器result的地址
print(list(result)) #[1, 8, 27, 64, 125]
reduce(func, list)
:functools模組中的一個高階函數,其中func必須有兩個引數。每次func結算的結果繼續和序列的下一個元素做累積計算。
#計算list2序列中各個數位的累加和
import functools #匯入模組
list2 = [1,2,3,4,5]
def func(a,b):
return a+b
result = functools.reduce(func,list2)
print(result) #15
filter(func, list)
:用於過濾序列,過濾掉不符合條件的元素,並返回一個filter物件。可用 list() 轉換為列表。
#過濾list3序列中所有的偶數,只留下奇數
list3 = [1,2,3,4,5,6,7,8,9]
def func(x):
return x%2 != 0
result = filter(func,list3)
result = list(result)
print(result) #[1,3,5,7,9]
檔案操作:
作用:把一些內容(資料)儲存存放起來,可以讓程式下一次執行的時候直接使用,而不必重新制作一份,省時省力。
檔案操作步驟:開啟檔案、讀寫等操作、關閉檔案。
open()
:開啟一個已經存在的檔案,或建立一個新檔案。
f = open(name, mode)
#name: 是要開啟的目標檔名的字串(可以包含檔案所在的具體路徑)
#mode: 設定開啟檔案的模式(存取模式):唯讀、寫入、追加等
#此時f為name檔案的檔案物件,可通過f執行之後的讀寫等操作
主存取模式 | 描述 |
---|---|
r | 以唯讀方式開啟檔案。檔案的指標將會放在檔案的開頭。這是預設模式(存取模式未指定時,即為唯讀模式)。 |
w | 開啟一個檔案只用於寫入。如果該檔案已存在則開啟檔案,並從開頭開始編輯,即原有內容會被刪除。如果該檔案不存在,建立新檔案。 |
a | 開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。 |
(b) | 以二進位制形式讀取 |
(+) | 可讀可寫 |
存取模式r+、w+、a+的區別:
r+
:沒有該檔案則報錯,檔案指標在開頭故能讀取資料
w+
:沒有該檔案會新建,檔案指標在開頭並會用新內容覆蓋原有內容,故無法讀取檔案內原有的資料
a+
:沒有該檔案會新建,檔案指標在結尾故不能讀取資料
寫入內容:write()
檔案物件.write('內容')
讀取內容:read()、readlines()、readline()。
檔案物件.read(num)
#num 表示要從檔案中讀取的資料的長度。不寫則預設讀取所有資料。其中換行符'\n'會佔一位
檔案物件.readnlines()
#按照行的方式把整個檔案的內容進行一次性讀取,並返回一個列表,其中每一行資料為一個元素
檔案物件.readline()
#一次讀取一行內容、重複呼叫readline()則依次讀取檔案中每一行的內容
移動檔案指標:seek()
檔案物件.seek(偏移量,起始位置)
#起始位置引數: 0開頭 1當前 2結尾
應用:
#使用 a 存取模式開啟檔案,通過改變檔案指標位置來讀取資料
f = open('test.txt','a')
f.seek(0,0) #此時可簡寫為 f.seek(0)
con = f.read()
f.close()
檔案備份案例:
#使用者輸入當前目錄下任意檔名,程式完成對該檔案的備份功功能(備份檔名為 xx[備份].字尾)
#1.接收使用者輸入的檔名
old_name = input('input yoru backup file name:')
#2.規劃備份檔名
index = old_name.rfind('.') #檔名中'.'的位置
if index > 0: #判斷檔名,防止出現'.txt'類的無效檔名
postfix = old_name[index:]
new_name = old_name[:index] + '[備份]' + postfix #利用字串的切片重新規劃備份檔名
#3.備份檔案寫入資料
old_f = open(old_name,'rb')
new_f = open(new_name,'wb')
while True: #迴圈讀取,防止檔案過大時卡死
con = old_f.read(1024)
if len(con) == 0: #讀取完成時
break
new_f.write(con)
new_f.close()
old_f.close()
檔案和資料夾的操作:
模組:使用 os 模組
import os
#1.檔案操作
#檔案重新命名,也可以重新命名資料夾
os.rename(目標檔名或路徑, 新檔名)
#檔案刪除,也可以刪除資料夾
os.remove(目標檔名)
#2.資料夾操作
#建立資料夾
os.mkdir(資料夾名字)
#刪除資料夾
os.rmdir(資料夾名字)
#3.目錄操作
#獲取當前目錄
os.getcwd()
#改變當前預設目錄
os.chdir(目錄資料夾)
#獲取目錄列表
os.listdir(目錄資料夾)
檔案和資料夾操作應用案例:
#批次修改檔名,既可新增指定字串,又能刪除指定字串
import os
#構造條件資料
flag = input('輸入操作型別(1為新增,2為刪除):')
#構造指定字串
str = input('請輸入指定字串:')
#找到所有檔案
file_list = os.listdir()
#新增或刪除指定字串
for i in file_list:
if flag == '1':
new_name = str + i
elif flag == '2':
num = len(str)
new_name = i[num:]
else:
print('操作模式輸入錯誤!')
break
#重新命名
os.rename(i, new_name)
類是對一系列具有相同特徵和行為的事物的統稱,是一個抽象的概念,不是真實存在的事物。物件是由類建立出來的真實存在的事物。
#建立類
class 類名(): #類名要滿足識別符號命名規則,同時遵循大駝峰命名習慣
程式碼
......
def 函數名(self): #self指呼叫該函數的物件
程式碼
#建立物件
物件名 = 類名()
類外面新增物件屬性:
物件名.屬性名 = 值
類外面獲取物件屬性:
物件名.屬性名
類裡面獲取物件屬性:
self.屬性名
綜合範例:
class Washer():
def wash(self):
print('wash the clothes!')
def get_size(self):
print(f'此洗衣機的尺寸是{self.width} X {self.height}')
haier1 = Washer()
haier1.width = 500
haier1.height = 300
haier2 = Washer()
haier2.width = 600
haier2.height = 400
print(haier1.width)
haier1.get_size()
haier2.get_size()
魔法方法: __init__() 、 __str__()、__del__()。
#1. __init__() 初始化物件。
#建立物件時預設被呼叫;不需開發者傳遞self引數,python直譯器會自動把當前物件參照傳遞過去。
class washer():
def __init__(self,width,height):
self.width = width
self.height = height
def print_info(self):
print(f'{self.width} X {self.height}')
h = washer(500,800)
h.print_info()
#輸出結果 500 X 800
#2. __str__() 使得用print輸出物件時,輸出該方法中return的資料,而不再輸出物件的記憶體地址。
def __str__(self):
return "這是洗衣機物件!"
print(h)
#輸出結果 這是洗衣機物件!
#3. __del__() 當刪除物件時,python直譯器會預設呼叫__del__()方法
def __del__(self):
print(f'{self}物件已經被刪除!')
del h
#輸出結果 <__main__.washer object at 0x000002531DF744F0>物件已經被刪除!
兩個案例:
烤地瓜
#需求:1.被烤時間和地瓜狀態相對應 2.使用者可按意願新增調料
class SweetPotato():
def __init__(self):
self.cook_time=0
self.cook_state='生的'
self.condiments=[]
def cook(self, time):
if time >=0:
self.cook_time += time
if 0<= self.cook_time < 3:
self.cook_state = '生的'
elif 3 <= self.cook_time < 5:
self.cook_state = '半生不熟'
elif 5 <= self.cook_time < 8:
self.cook_state = '熟了'
elif self.cook_time >= 8:
self.cook_state = '糊了!'
else:
print('時間刺客?!')
def add_condiment(self, con):
self.condiments.append(con)
def __str__(self):
return f'這個地瓜烤了{self.cook_time}分鐘,狀態是{self.cook_state},新增的調料有{self.condiments}'
p = SweetPotato()
p.add_condiment('番茄醬')
print(p)
p.cook(8)
p.add_condiment('芥末')
print(p)
# 這個地瓜烤了0分鐘,狀態是生的,新增的調料有['番茄醬']
# 這個地瓜烤了8分鐘,狀態是糊了!,新增的調料有['番茄醬', '芥末']
搬傢俱
#需求 將小於房子剩餘面積的傢俱擺放到房子中
class Furniture():
def __init__(self,name,area):
self.name = name
self.area = area
class House():
def __init__(self,adress,area):
self.adress = adress
self.area = area
self.free_area = area
self.furniture = []
def add_furniture(self,item):
if self.free_area >= item.area:
self.furniture.append(item.name)
self.free_area -= item.area
else:
print('傢俱太大,剩餘面積不足,無法容納')
def __str__(self):
return f'這個房子的地址是{self.adress},總面積是{self.area},當前剩餘面積是{self.free_area},傢俱有{self.furniture}'
bed = Furniture('雙人床',6)
sofa = Furniture('沙發',10)
court = Furniture('高爾夫球場',1000)
house = House('陸家嘴',200)
print(house)
house.add_furniture(bed)
house.add_furniture(sofa)
house.add_furniture(court)
print(house)
#這個房子的地址是陸家嘴,總面積是200,當前剩餘面積是200,傢俱有[]
#傢俱太大,剩餘面積不足,無法容納
#這個房子的地址是陸家嘴,總面積是200,當前剩餘面積是184,傢俱有['雙人床', '沙發']
繼承: Python物件導向的繼承指的是多個類之間的所屬關係,即子類預設繼承父類別的所有屬性和方法,具體如下:
#定義父類別A
class A(object):
def __init__(self):
self.num = 1
def infor_print(self):
print(self.num)
#定義子類B,繼承父類別A
class B(A):
pass
#建立物件,驗證物件繼承
result = B()
result.info_print()
在python中,所有類預設繼承object類,object類是頂級類或基礎類別;其他子類叫派生類。
拓展:python2中的經典類 和 python3中的新式類
#經典類(不由任意內建型別派生出的類)
class 類名:
程式碼
......
#新式類
class 類名(object):
程式碼
......
#在今後的學習和運用中,統一使用新式類
單繼承:一個子類繼承一個父類別,這種單一的繼承關係稱為單繼承。
多繼承:一個子類同時繼承多個父類別。
class 子類(父類別A,父類別B,父類別C)
#當兩個父類別中的屬性和方法有同名時,優先繼承第一個父類別中的同名屬性和方法,即繼承A類。
子類重寫父類別同名屬性與方法:在子類中可以重寫與父類別中同名的屬性和方法。子類建立的物件呼叫屬性和方法時,會呼叫子類中重寫的屬性和方法。
拓展: **__mro__**順序 方法檢視類的繼承層級順序。
print(類名.__mro__)
子類呼叫父類別同名屬性和方法:在子類中重寫了父類別中同名屬性與方法的情況下,呼叫父類別中的同名屬性和方法。
class 子類B(父類別A):
def 同名方法(self):
#如果之前呼叫了父類別的屬性和方法,則父類別屬性會覆蓋子類屬性,故在呼叫子類屬性前,先呼叫子類自己的初始化
self.__init__(self)
程式碼
def 呼叫父類別方法(self):
#呼叫父類別方法,為保證呼叫到的屬性也是父類別的屬性,必須在呼叫方法前呼叫父類別的初始化
父類別A.__init__(self)
父類別A.同名方法(self)
多層繼承:一般指大於兩層的繼承關係。
class A(object):
...
class B(A):
...
class C(B): #多層繼承
...
super()呼叫父類別方法:自動查詢父類別,直接呼叫父類別的屬性方法,呼叫順序遵循__mro__類屬性的順序。
class A(object)
class B(A)
class C(B):
#方法一:原始方法
def useAB(self):
A.__init__(self)
A.同名方法(self)
B.__init__(self)
b.同名方法(self)
#方法二:super()方法
#方法2.1 super(當前類名,self).函數()
def useAB(self):
super(C,self).__init__()
super(C,self).同名方法()
#此時會呼叫父類別B的方法;若想呼叫A類的方法,需要在B類的同名方法中新增同樣的super方法程式碼來呼叫A類
#方法2.2 super().函數()
def useAB(self):
super().__init__(self)
super().同名方法()
#同樣呼叫父類別B的方法;無法直接呼叫父類別的父類別A的屬性和方法
私有許可權
**設定私有屬性和方法:在屬性名和方法名 **前面加上兩個下劃線。
私有屬性和私有方法只能在類記憶體取和修改,即子類無法繼承或直接存取父類別的私有屬性和方法。
class A(object):
def __init__(self):
self.name = 'A'
self.__money = 99999 #私有屬性
def __CostMoney(self,money): #私有方法
self.__money -= money
獲取和修改私有屬性值:可在類內定義公有函數來獲取和修改 私有屬性值,在類外呼叫該函數來實現獲取和修改私有屬性功能。
#一般在類內用函數名get_xx來獲取私有屬性,用set_xx來修改私有屬性
class A(object):
def __init__(self):
self.__money = 99999
def get_money(self):
return self.__money
def set_money(self,new_money):
self.__money = new_money
class B(A):
pass
b = B()
b.get_money() #成功獲取父類別中的私有屬性
b.set_money(0) #成功修改父類別中的私有屬性
多型:一種使用物件的方式,子類重寫父類別方法,呼叫不同子類物件的相同父類別方法,可以產生不同的執行結果。即傳入不同的物件,產生不同的結果。
類屬性和範例屬性:類屬性即類所擁有的屬性,它為該類所有物件共有。類屬性可以用 類物件 或 範例物件 存取。
類屬性只能通過類物件修改。
#修改類屬性
類名.屬性 = 值
類方法:需要用裝飾器 @classmethod
來標識其為類方法,類方法第一個引數必須是類物件,一般以 cls
作為第一個引數。
class A(object):
__num = 777
@classmethod
def get_num(cls):
return cls.__num
obj = A()
print(obj.get_num())
靜態方法:通過裝飾器 @staticmethod
進行修飾,靜態方法即不需要傳遞類和物件的方法,有利於減少不必要的記憶體佔用和效能消耗。
class A(object):
@staticmethod
def info_print():
print('這是A類')
異常的定義:直譯器檢測到錯誤時無法繼續執行,並出現一些錯誤的提示,這就是所謂的異常。
異常的作用:使得直譯器檢測到錯誤時,轉而執行另一句沒錯誤的語句,使得程式不因一個錯誤而停止下來。
基本寫法:
try:
可能發生錯誤的程式碼
except:
出現異常時執行的程式碼
else:
沒有異常時執行的程式碼
finally:
無論是否異常都要執行的程式碼
體驗案例:
#需求:嘗試以r模式開啟檔案,若檔案不存在(發生錯誤),則以w方式開啟
try:
f = open('test.txt','r')
except:
f = open('test.txt','w')
捕獲指定異常:
try:
print(num)
except (NameError, ZeroDivisionError) as result:
print(result) #捕獲的異常描述資訊
num = 777
print(num)
#若嘗試執行程式碼的異常型別和要捕獲的異常型別不一致,則無法捕獲異常
#一般try下方只放一行嘗試執行的程式碼
捕獲所有異常:利用 Exception 類
#Exception是所有程式異常類的父類別
try:
可能錯誤的程式碼
except Exception as result:
print(result)
異常中的 else 和 finally:
try:
f = open('test.txt','r')
except Exception as result:
f = open('test.txt','w')
print(result)
else: # try 下方的程式碼無異常時執行的程式碼
print('程式碼沒有異常和錯誤')
finally: #無論有無異常都要執行的程式碼,如關閉檔案
f.close()
異常的傳遞:
import time
try:
f = open('test.txt') #預設開啟模式為唯讀
#嘗試迴圈讀取內容
try:
while True:
con = f.readline()
#無內容時退出迴圈
if len(con) == 0:
break
time.sleep(2)
print(con)
except:
#在命令提示字元中按下 Ctrl+C 終止程式
print('程式被意外終止')
except:
print('檔案不存在')
自定義異常: 丟擲自定義異常的語法為raise 異常類物件
#自定義異常類,繼承Exception
class ShortInputError(Exception):
def __init__(self,length,min_length):
self.length=length
self.min_length=min_length
#設定丟擲異常的描述資訊
def __str__(self):
return f'輸入長度為{self.length},不能少於{self.min_length}個字元'
def main(): #封裝程式碼
try:
con = input('請輸入密碼: ')
if len(con) < 6:
raise ShortInputError(len(con),6)
except Exception as result:
print(result)
else:
print('密碼輸入完成')
main()
瞭解模組:Python模組(Module),是一個Python檔案,包含了Python物件定義和語句。
匯入和呼叫模組:
#匯入及呼叫模組
#寫法一
import 模組名 #匯入模組中的所有程式碼
模組名.功能名()
#寫法二
from 模組名 import 功能1,功能2... #單個呼叫某功能
功能名() #即不需要在功能前寫 "模組名."
#寫法三
from 模組名 import *
功能名()
#一般用第一種寫法
利用as定義別名:定義別名後,使用時要用定義的別名
#模組定義別名
import 模組名 as 別名
#功能定義別名
from 模組名 import 功能 as 別名
製作模組:模組名字就是py檔案的名字。自定義模組名必須要符合識別符號命名規則。
#只會在當前檔案中呼叫下列測試程式碼,其他匯入的檔案內不符合該條件,也就不會執行測試程式碼
# __name__ 是系統變數,是模組的識別符號。如果在自身模組裡,則其值為 '__main__';否則是所在模組的名字
if __name__ == '__main__':
測試模組功能程式碼
模組定位順序:當匯入一個模組,Python直譯器對模組位置的搜尋順序是:
當前目錄 > 搜尋在shell變數PYTHONPATH下的每個目錄 > 作業系統的預設python路徑
注意:
自己的檔名不要和已有模組名重複,否則模組功能無法使用。
使用from 模組名 import 功能
時,若功能名字重複,則呼叫最後定義的或最後匯入的功能。
當使用 import 模組名
的寫法呼叫模組時,不需要擔心功能名重複。
__all__
列表:如果一個模組檔案中有__all__
變數列表,當使用from 模組名 import *
匯入該模組時,則只能匯入__all__
列表中的元素。
包:包將有聯絡的模組組織在一起,放到同一個資料夾下,並且在這個資料夾內自動生成一個名字為__init__.py
的檔案,這個檔案控制著包的匯入行為。
建立包:在Pycharm中 New -> Python Package -> 輸入包名 - > [OK] 即可新建一個包。
匯入包:
#方法一
import 包名.模組名
包名.模組名.功能
#方法二
#注意,必須在 __init__.py 檔案中新增 __all__ = [] 來控制允許匯入的模組列表
from 包名 import *
模組名.功能
#使用物件導向程式設計思想完成學員管理系統的開發
#為了方便維護程式碼,一般一個角色一個程式檔案
#專案要有主程式入口,習慣為main.py
#系統要求:學員資料儲存在檔案中
#系統功能:新增學員、刪除學員、修改學員資訊、查詢學員資訊、顯示所有學員資訊、儲存學員資訊、退出系統等功能
#student.py
#學員類
class Student(object):
def __init__(self,name,gender,tel):
#姓名、性別、手機號
self.name = name
self.gender = gender
self.tel = tel
def __str__(self):
return f'{self.name},{self.gender},{self.tel}'
#mangerSystem.py
#儲存資料的: student.data
#儲存資料的形式: 列表儲存學員物件
#系統功能: 新增、刪除、修改、查詢、顯示、儲存學員資訊
#管理系統類
class StudentManager(object):
def __init__(self):
#儲存資料所用列表
self.student_list = []
#一. 程式入口函數,啟動程式後執行的函數
def run(self):
#1. 載入學員資訊
self.load_student()
while True:
#2. 顯示功能選單
self.show_menu()
#3. 使用者輸入目標功能序號
menu_num = int(input('請輸入您需要的功能序號: '))
#4. 根據使用者輸入的序號執行相應功能
if menu_num == 1:
# 新增學員
self.add_student()
elif menu_num == 2:
# 刪除學員
self.del_student()
elif menu_num == 3:
# 修改學員資訊
self.modify_student()
elif menu_num == 4:
# 查詢學員資訊
self.search_student()
elif menu_num == 5:
# 顯示所有學員資訊
self.show_menu()
elif menu_num == 6:
# 儲存學員資訊
self.save_student()
elif menu_num == 7:
# 退出系統 - 退出迴圈
break
#二. 系統功能函數
#2.1 顯示功能選單 -- 靜態方法
@staticmethod
def show_menu():
print('請選擇如下功能: ')
print('1.新增學員')
print('2.刪除學員')
print('3.修改學員資訊')
print('4.查詢學員資訊')
print('5.顯示所有學員資訊')
print('6.儲存學員資訊')
print('7.退出系統')
#2.2 新增學員
def add_student(self):
#1. 使用者輸入
name = input('請輸入姓名: ')
gender = input('請輸入性別: ')
tel = input('請輸入手機號: ')
#2. 建立學員物件 -- 先匯入student.py模組
student = Student(name,gender,tel)
#3. 將物件新增到學員列表
self.student_list.append(student)
#2.3 刪除學員
def del_student(self):
#1. 使用者輸入目標學員姓名
del_name = input('請輸入要刪除的學員姓名:')
#2. 如果使用者輸入的目標學員存在則刪除,否則提示不存在
for i in self.student_list:
if i.name == del_name:
self.student_list.remove(i)
break
else:
print('查無此人!')
#2.4 修改學員資訊
def modify_student(self):
#1. 使用者輸入目標學員姓名
modify_name = input('請輸入要修改的學員姓名: ')
#2. 如果使用者輸入的目標學員存在,則修改資訊,否則提示不存在
for i in self.student_list:
if i.name == modify_name:
i.name = input('請輸入學員姓名: ')
i.gender = input('請輸入學員性別: ')
i.tel = input('請輸入學員手機號: ')
print('修改成功!')
break
else:
print('查無此人!')
#2.5 查詢學員資訊
def search_student(self):
#1. 使用者輸入目標學員姓名
search_name = input('請輸入要查詢的學員姓名: ')
#2. 若存在,列印學員資訊,否則提示不存在
for i in self.student_list:
if i.name == search_name:
print(f'姓名{i.name},性別{i.gender},手機號{i.tel}')
break
else:
print('查無此人!')
#2.6 顯示所有學員資訊
def show_student(self):
print('姓名\t性別\t手機號')
for i in self.student_list:
print(f'{i.name}\t{i.gender}\t{i.tel}')
#2.7 儲存學員資訊
def save_student(self):
# 拓展 __dict__方法,以字典方式返回類和物件內的屬性
#1. 開啟檔案
f = open('student.data','w')
#2. 檔案寫入學員資料 - 先將學員物件資料轉換成列表字典資料再做儲存
new_list = [i.__dict__ for i in self.student_list]
# 檔案內資料要求為字串型別,故要先轉換資料型別為字串才能寫入檔案
f.write(str(new_list))
#3. 關閉檔案
f.close()
#2.8 載入學員資訊
def load_student(self):
#嘗試以"r"模式開啟資料檔案,有異常則用"w"模式開啟;存在則讀取資料
try:
f = open('student.data','r')
except:
f = open('student.data','w')
else:
#1. 讀取資料
data = f.read()
#2. 先將檔案中的 字串型字典資料 轉換為 物件資料 後再儲存到學員列表
new_list = eval(data)
self.student_list = [Student(i['name'],i['gender'],i['tel']) for i in new_list]
finally:
#3. 關閉檔案
f.close()
#main.py
#匯入模組
#from managerSystem import *
#啟動管理系統
#if __name__ == '__main__':
student_manager = StudentManager()
student_manager.run()