本文為TesterHome社區(qū)同學耿曉分享的Python基礎(chǔ)系列文章:作者的話:
再梳理一遍Python系列知識點,夯實基礎(chǔ),無他,唯手熟爾!
Python系列總結(jié)都是我自己平時的學習筆記,如果有不正確的地方,希望各位佬兒哥指正糾偏~
測試基礎(chǔ)-Python篇 基礎(chǔ)①
變量名命名規(guī)則 - 遵循PEP8原則
普通變量:max_value
全局變量:MAX_VALUE
內(nèi)部變量:_local_var
和關(guān)鍵字重名:class_
函數(shù)名:bar_function
類名:FooClass
布爾類型的變量名用 is,has 這類詞語前綴
is_superuser
has_errors
allow_empty
釋義為數(shù)字的單詞
port
age
radius
以_id 為結(jié)尾的單詞
user_id
port_id
以 length/count 開頭或結(jié)尾的詞
length_of_username
max_length
users_count
注:不要用名詞的復數(shù)形式來作為 int 類型的變量名,因為名詞的負數(shù)形式更像是一個容器。建議使用 number_of_apples 或 trips_count;
超短命名
數(shù)組索引三劍客 i、j、k
某個整數(shù) n
某個字符串 s
某個異常 e
文件對象 fp
變量注解
在Python3.5之后,可以使用類型注解功能來注明變量類型,在變量后添加類型,并用冒號隔開;
def repeat_message(message: str, count: int) -> str:
return message * count
算術(shù)運算符
不同類型變量之間的計算
獲取輸入的信息-input
input 輸入的數(shù)據(jù)類型都是字符串類型
格式化輸出
vb1 = 'Tom'print('hello %s' % vb1)vb2 = 5print('有符號十進制整數(shù):%d' % vb2)print('輸出顯示位數(shù)的整數(shù):%06d' % vb2)vb3 = 3.1415926print('保留兩位小數(shù):%.2f' % vb3)print('保留三位小數(shù):%.3f' % vb3)vb4 = 80print('正確率為:%d%%' % vb4)--------------------------------------------------------------------hello Tom有符號十進制整數(shù):5輸出顯示位數(shù)的整數(shù):000005保留兩位小數(shù):3.14保留三位小數(shù):3.142正確率為:80%
邏輯運算
and:
條件1 and 條件2
or:
條件1 or 條件2
not:(取反)
not 條件
a = 10b = 20c = 10if c == a and c == b:print('right')else:print('error')-------------------------------error
a = 10b = 20c = 10if c == a or c == b:print('right')else:print('error')-------------------------------right
循環(huán)-while
初始條件設(shè)置 -- 通常是重復執(zhí)行的 計數(shù)器
while 條件 1:
條件滿足時,做的事情 1
條件滿足時,做的事情 2
條件滿足時,做的事情 3
……
while 條件 2:
條件滿足時,做的事情 1
條件滿足時,做的事情 2
條件滿足時,做的事情 3
……
處理條件 2
處理條件 1
print 函數(shù)增強
在默認情況下,print 函數(shù)輸出內(nèi)容之后,會自動在內(nèi)容末尾增加換行;
如果不希望末尾增加換行,可以在 peint 函數(shù)輸出內(nèi)容的后面增加,end=''
其中''中間可以指定 print 函數(shù)輸出內(nèi)容之后,繼續(xù)希望現(xiàn)實的內(nèi)容;
語法格式如下:
print('*',end='')
轉(zhuǎn)義字符
列表
列表通過索引取值,列表索引從0開始,且不能超過范圍;
len(列表)--獲取列表的長度
列表.count(數(shù)據(jù))--數(shù)據(jù)在列表中出現(xiàn)的次數(shù)
列表.index(數(shù)據(jù))--獲取數(shù)據(jù)第一次出現(xiàn)的索引
del 列表 [索引]--刪除指定索引的數(shù)據(jù)
列表.remove[數(shù)據(jù)]--刪除第一個出現(xiàn)的指定數(shù)據(jù)
列表.pop--刪除末尾數(shù)據(jù)
列表.pop(索引)--刪除指定索引的數(shù)據(jù)
列表.insert(索引,數(shù)據(jù))--在指定位置插入數(shù)據(jù)
列表.append(數(shù)據(jù))--在末尾追加數(shù)據(jù)
列表.extend(列表 2)--將列表2的數(shù)據(jù)追加到列表1
列表.sort()--升序排序
列表.sort(reverse=True)--降序排序
列表.reverse() 反轉(zhuǎn)/逆序
元祖
Tuple(元組)與列表類似,不同之處在于元組的 元素不能修改;
創(chuàng)建空元組:info_tuple = ()
元組中只包含一個元素時,需要在元素后面添加逗號:info_tuple = (50, )
len(元組)--獲取元組的長度 n+1;
元組.count(數(shù)據(jù))--數(shù)據(jù)在元組中出現(xiàn)的次數(shù);
元組 [索引]--從元祖中取值;
元組.index(數(shù)據(jù))--獲取數(shù)據(jù)第一次出現(xiàn)的索引。
元組和列表之間的轉(zhuǎn)換
字典
Python3.6 之后的字典是有序的,如果解釋器版本沒有那么新,也可以使用 collections 模塊里的 OrderedDict 方法保證字典的有序性。
OrderedDict 與新版字典在比較上面的區(qū)別:在對比兩個內(nèi)容相同但順序不同的字典時,新版字典會返回 True,OrderedDict 則會返回 False。
from collections import OrderedDict
d = OrderedDict()
d['one'] = 1
d['two'] = 2
print(d)————————————————————
OrderedDict([('one', 1), ('two', 2)])
鍵必須是唯一的;
值可以取任何數(shù)據(jù)類型,但鍵只能使用字符串、數(shù)字或元組;
字典.keys()--所有 key 列表;
字典.values()--所有 value 列表;
字典.items()--所有(key,value)元組列表;
字典 [key]--可以從字典中取值,key 不存在會報錯;
1.返回的數(shù)據(jù)類型類似列表,但不是真正意義的列表,沒有 append() 方法;
2.但是可以用于 for 循環(huán);
3.可以用 list() 方轉(zhuǎn)換成真正的列表;
字典.get(key)--可以從字典中取值,key 不存在不會報錯;
del 字典 [key]--刪除指定鍵值對,key 不存在會報錯;
字典.pop(key)--刪除指定鍵值對,并且返回刪除鍵對應的值,key 不存在會報錯;
字典.pop(key, default=msg)--刪除指定鍵值對,并且返回刪除鍵對應的值,key 不存在不會報錯,會返回 msg;
字典 popitem() 方法返回并刪除字典中的最后一對鍵和值。
字典.clear()--清空字典;
字典 [key] = value
如果 key 存在,修改數(shù)據(jù)
如果 key 不存在,新建鍵值對
字典.setdefault(key,value)
如果 key 存在,不會修改數(shù)據(jù)
如果 key 不存在,新建鍵值對
字典.update(字典2)--將字典2的數(shù)據(jù)合并到字典1,如果字典2中有和字典 1 重復的鍵值對,則替換字典 1 中的鍵值對;
生成字典的方法:d = dict.fromkeys(['name','age','code'],0) #0 為默認值
字符串
拼接多個字符串,使用 str.join 和 +=同樣好用;
len(字符串)--獲取字符串的長度;
字符串.count(字符串)--小字符串在大字符串中出現(xiàn)的次數(shù);
字符串 [索引]--從字符串中取出單個字符;
字符串.index(字符串)--獲得小字符串第一次出現(xiàn)的索引;
string.istitle() | 如果 string 是標題化的 (每個單詞的首字母大寫) 則返回 True;
string.startswith(str) | 檢查字符串是否是以 str 開頭,是則返回 True;
string.endswith(str) | 檢查字符串是否是以 str 結(jié)束,是則返回 True;
string.find(str, start=0, end=len(string)) | 檢測 str 是否包含在 string 中,如果 start 和 end 指定范圍,則檢查是否包含在指定范圍內(nèi),如果是返回開始的索引值,否則返回 -1
;
string.index(str, start=0, end=len(string)) | 跟 find() 方法類似,不過如果 str 不在 string 會報錯;
string.replace(old_str, new_str, num=string.count(old)) | 把 string 中的 old_str 替換成 new_str,如果 num 指定,則替換不超過 num 次;
string.capitalize() | 把字符串的第一個字符大寫;
string.title() | 把字符串的每個單詞首字母大寫;
string.lower() | 轉(zhuǎn)換 string 中所有大寫字符為小寫;
string.upper() | 轉(zhuǎn)換 string 中的小寫字母為大寫;
string.swapcase() | 翻轉(zhuǎn) string 中的大小寫;
字符串 - 切片
切片方法適用于字符串、列表、元組;
字符串 [開始索引:結(jié)束索引:步長];
切片:正反向索引(正:從 0 開始,反:從-1 開始)
切片索引:[start
step]
start:開始截取的位置,包含在截取內(nèi)容內(nèi)
end:結(jié)束截取的位置,結(jié)束截取的位置并不包含
step:截取的步長,默認值為 1
step:為正,表示從左到右進行截取,start 必須在 end 之前(從左開始算前,下標必須從左到右)
step:為負,表示從右到左進行截取,start 必須在 end 之前(從右開始算前,下標必須從右到左)
s = 'hello,world'
print(s[:]) # 取全部
print(s[1:]) # 從第 2 位取到最后
print(s[:-1]) # 從開始取到倒數(shù)第二位
print(s[::2]) # 步長為 2
print(s[::-1]) # 反序
指定的區(qū)間屬于左閉右開型 [開始索引, 結(jié)束索引) => 開始索引 >= 范圍 < 結(jié)束索引
從 起始位開始,到 結(jié)束位的前一位 結(jié)束(不包含結(jié)束位本身)
從頭開始,開始索引 數(shù)字可以省略,冒號不能省略
到末尾結(jié)束,結(jié)束索引 數(shù)字可以省略,冒號不能省略
步長默認為 1,如果連續(xù)切片,數(shù)字和冒號都可以省略
索引的順序和倒序:
在 Python 中不僅支持 順序索引,同時還支持 倒序索引
所謂倒序索引就是 從右向左 計算索引
最右邊的索引值是 -1,依次遞減
字符串格式化
# 將username靠右對齊,左側(cè)補空格一共到20位username = 'Lili'print(f'{username:>20}')-------------------------------------
Lili
username = 'Lily'sore = 10print('{0}:{0}的成績是{1}'.format(username, sore))
集合
集合是一個無序的可變?nèi)萜黝愋停畲蟮奶攸c就是成員不能重復
要初始化一個空集合只能調(diào)用 set() 方法,因為{}表示的是一個空字典,而不是一個空集合
集合也有自己的推導式-nums = {n for n in range(10) if n % 2 == 0}
集合是可變類型,可以通過.add() 追加元素
可以使用 update 方法可以將一個可迭代元素更新到集合中
s1 = set([1,2,3])s2 = set([2,3,4])s1.update(s2)s1.update('hello')print(s1)------------------------{1, 2, 3, 4, 'o', 'h', 'e', 'l'}
使用.remove() 可以刪除集合中的元素,但元素不存在會報錯-KeyError:
使用.discard() 可以刪除集合中的元素,元素不存在也不會報錯
集合的元素不可以修改,只能先刪再加
我們可以使用 in 判斷某個元素是否在某個集合中,不能在集合中取值,只能使用 for 循環(huán)遍歷集合中的元素
集合只能存放可哈希對象
s1 = set([1,2,3])s1.add([1])-----------------------TypeError: unhashable type: 'list'
集合的運算
集合支持集合運算,比如交集、并集、差集。所有的操作都可以用兩種方式:方法和運算符;
fruits_1 = {'apple','orange','pineapple'}fruits_2 = {'tomato','orange','grapes','mango'}print(fruits_1 & fruits_2)-----------------------------{'orange'}
fruits_1 = {'apple','orange','pineapple'}fruits_2 = {'tomato','orange','grapes','mango'}print(fruits_1 | fruits_2)----------------------------------------------------------{'tomato', 'pineapple', 'orange', 'apple', 'grapes', 'mango'}
fruits_1 = {'apple','orange','pineapple'}fruits_2 = {'tomato','orange','grapes','mango'}print(fruits_1 - fruits_2)------------------------------------{'apple', 'pineapple'}
fruits_1 = {'apple','orange','pineapple'}fruits_2 = {'tomato','orange','grapes','mango'}print(fruits_1.symmetric_difference(fruits_2)){'apple', 'mango', 'tomato', 'pineapple', 'grapes'}
fruits_1 = {'apple','orange','pineapple'}fruits_2 = {'apple','orange','pineapple','water'}print(fruits_1.issubset(fruits_2))print(fruits_2.issubset(fruits_1))--------------------------------------------------TrueFalse
Python 循環(huán)結(jié)構(gòu)
什么時候用 for:當循環(huán)次數(shù)是一定的,或者是循環(huán)對象是一定的,比如說在一個固定的字符串或列表中進行循環(huán),那么最好使用 for
什么時候用 while:當循環(huán)次數(shù)不是一定的,只是滿足某個條件時才進行循環(huán),那么最好使用 while
沒有 do…while…循環(huán)
循環(huán)里面加 else:當循環(huán)執(zhí)行完畢時,else 才會執(zhí)行;如果循環(huán)在中間退出,則 else 不會運行
break&continue:不管是 break 還是 continue 都只作用于當前循環(huán)
匿名函數(shù)-lambda
lambda 關(guān)鍵字能夠幫我們創(chuàng)建小型的匿名函數(shù):
lambda x:express
lambda 返回的是該匿名函數(shù)的指針
func = lambda x,y:x*y
print(func(2,3))
類
類定義
類方法
實例方法
1、只能通過對象 (實例) 調(diào)用的方法
2、實例方法在定義時總是以 self 作為第一個參數(shù)
3、實例方法在調(diào)用時不需要傳入 self,這個實例本身會自動傳到方法中作為 self
初始化方法 (init())
1.不需要顯式調(diào)用,在初始化對象時會有 python 自動調(diào)用
2.初始化方法一般只在定義對象屬性的時候才會定義
類方法
1、可以直接通過類名調(diào)用的方法,也可以通過實例調(diào)用
2、類方法必須通過@classmethod裝飾器進行裝飾
3、所有的類方法第一個參數(shù)必須是 cls
4、類方法不能訪問實例屬性,只能訪問類屬性
屬性方法
使用場景:屬性方法對應的屬性的值無法直接確定,要通過一系列的操作才能得到這個值,而且用戶不關(guān)心這個操作過程,只想得到這個值。
定義:當成屬性使用的方法,調(diào)用屬性方法時不需要加 ()
靜態(tài)方法
1、通過@staticmethod裝飾器來進行裝飾的方法
2、靜態(tài)方法既不能訪問實例屬性,也不能訪問類屬性
3、可以通過類名直接調(diào)用,也可以通過對象調(diào)用
類的三大特征
類的反射
反射原理
通過字符串的形式在運行時動態(tài)修改程序的變量、方法及屬性,所有的修改都在內(nèi)存中進行,所以他并不會實際修改代碼,主要目的就是提高代碼在運行時的靈活性;
反射相關(guān)的方法
hasattr 輸入一個字符串,判斷對象有沒有這個方法或?qū)傩裕?br>getattr 獲取對象屬性值或方法的引用,如果是方法,則返回方法的引用,如果是屬性,則返回屬性的值,如果該方法或?qū)傩圆淮嬖冢瑒t拋出異常;
setattr 動態(tài)添加一個方法或?qū)傩裕?br>delattr 動態(tài)刪除一個方法或?qū)傩浴?/span>
異常處理
Python 異常處理依賴的關(guān)鍵字:
try
except
else
finally
try
try 塊里面放置所有可能引起異常的代碼,一個異常處理塊里面只能有一個 try;
except
放置要處理的異常類型和相應語句塊,用于表明該 except 要處理的異常類型;
一個異常處理塊里面可以跟 1 到 n 個 except 塊;
每個 except 塊后面可以跟 1 到 n 個異常類型,也可以不跟任何異常類型;
else
如果 try 塊里面的語句沒有引起異常,則會運行 else 里面的語句;
finally
主要用于回收再 try 塊里面打開的物理資源,異常處理機制會保證 finally 塊一定會被執(zhí)行;
異常處理語法結(jié)構(gòu)
1.只有 try 是必須的
2.如果沒有 try,就不能有 except 和 finally
3.except 塊和 finally 塊都是可選的,但 except 和 finally 必須出現(xiàn)其中之一,也可以同時出現(xiàn)
4.可以有多個 except 塊,但捕獲父類異常的 except 塊要寫在捕獲子類異常的 except 塊的后面
5.多個 except 塊必須位于 try 塊之后,finally 塊必須位于所有塊的最后
IO 讀寫 - 文本文件
open (path,mode)
默認是 r:只讀模式,文件必須事先存在,不主動生成文件,從文件開頭開始讀;
r+:讀寫模式,文件也必須事先存在,不主動生成文件,從文件開頭開始讀或?qū)懀?br>w:只寫模式,如果用 w 模式打開,一律會清空之前文件的所有內(nèi)容,如果文件不存在,則自動創(chuàng)建文件,從頭開始寫;
w+:讀寫模式,也會清空之前文件的所有內(nèi)容,如果文件不存在,則自動創(chuàng)建文件,從頭開始寫;
a:追加模式,只寫,不會清空以前文件的內(nèi)容,主動生成文件,從文件尾開始寫入;
a+:追加模式,讀和寫,不會清空以前文件的內(nèi)容,主動生成文件,從文件尾開始寫入或讀??;
二進制讀寫,一般用于圖片或音視頻:rb+,wb+,ab+;
查看和設(shè)置文件指針位置:
with open('user.txt', 'a+') as f:
# 將文件指針重置至開始位置(這樣就不會導致f.readlines()讀不到數(shù)據(jù)了) f.seek(0)
# 返回文件指針位置 print(f.tell())
with 是 python 中的上下文管理器,它會自動幫你管理文件的句柄
with open(r'D:\testlog.txt') as f:for line in f.readlines():
print(line,end='')
文件與文件夾
windows 文件路徑用反斜線,Linux 文件路徑用正斜線,要想將程序在不同系統(tǒng)上運行,則可用 os.path.join() 方法;
myFiles = ['accounts.txt','details.csv','invite.docx']
for filename in myFiles:
print(os.path.join('c:\\User\\asweigart',filename))-----------------------------------------------------------------------------------------c:\User\asweigart\accounts.txtc:\User\asweigart\details.csvc:\User\asweigart\invite.docx
其余相關(guān)知識點附張圖吧:

多線程和多進程編程
概念
程序:指的是一段靜態(tài)的代碼指令;
進程:正在執(zhí)行的程序,將靜態(tài)的執(zhí)行代碼運行起來,進程內(nèi)擁有該程序執(zhí)行所需的全部資源;
線程:是指正在執(zhí)行程序的最小單元。一個進程中至少必須有一個線程(主線程),在程序中線程是獨立的可運行的流;
多線程:在單個程序中同時運行多個不同的線程,完成不同的工作;
進程特征
獨立性:進程是系統(tǒng)中獨立存在的實體,擁有獨立的資源空間;
動態(tài)性:進程擁有自己的生命周期;
并發(fā)性:多個進程可以在單個處理器上并發(fā)執(zhí)行,互不影響;
線程特征
每個線程都有自己的堆棧,自己的程序計數(shù)器,自己的局部變量,這里體現(xiàn)了程序的獨立性;
在相同父進程下的所有線程共享進程內(nèi)所有資源,可以實現(xiàn)線程間的消息互通;
多個線程之間也可以并發(fā)執(zhí)行,互不影響;
創(chuàng)建多線程-threading
1.使用 threading 模塊的 Thread 類的構(gòu)造器創(chuàng)建線程對象。在創(chuàng)建線程對象時使用 target 參數(shù)指定函數(shù)線程的執(zhí)行體;
2.調(diào)用線程對象的 start() 方法啟動線程;
通過 join 方法去阻塞主線程
d = Demo()t1 = threading.Thread(target=d.music,args=('搖籃曲',))t2 = threading.Thread(target=d.movie, args=('灰太狼',))t1.start()t2.start()t1.join()t2.join()
設(shè)置守護線程
主線程結(jié)束后立即結(jié)束所有設(shè)置為守護線程的子線程;
多線程鎖
import threadingbalance = 0lock = threading.RLock()def change_it(n):lock.acquire()try:
global balance
balance += n
balance -= nfinally:
lock.release()def run_threading(n):for i in range(100000000):
change_it(n)t1 = threading.Thread(target=run_threading, args=(5,))t2 = threading.Thread(target=run_threading, args=(5,))t1.start()t2.start()t1.join()t2.join()
GIL 全局解釋器鎖
什么是 GIL 全局解釋器鎖:
GIL(Global Interpreter Lock)是 Python 的一個重要特性,它是一種機制,用于保護多線程環(huán)境下共享內(nèi)存數(shù)據(jù)的完整性。它鎖定了整個解釋器,只允許一個線程同時執(zhí)行 Python 字節(jié)碼,從而避免多線程下出現(xiàn)數(shù)據(jù)競爭問題。這意味著即使使用多核 CPU,Python 程序也不能充分利用多核優(yōu)勢。GIL 在性能上可能帶來一定的影響,因此不適合處理需要大量的 CPU 運算的任務(wù)。
什么條件下會釋放 GIL:
當前活躍線程遇到 IO 等待,比如要訪問網(wǎng)絡(luò)或建立數(shù)據(jù)庫鏈接等情況;
活躍線程執(zhí)行了 100 個字節(jié)碼的程序后,GIL 也會釋放該線程的鎖,然后與其他線程參與競爭;
python 的多線程適合場景:
python 的多線程只適合于 IO 密集型應用,對于計算密集型的應用最好使用多進程或協(xié)程的方式解決;
可迭代對象
迭代器
任何實現(xiàn)了iter和next方法的對象都是迭代器(這兩個方法必須同時實現(xiàn));
其中iter會返回迭代器本身;
next會返回迭代器中的下一個元素,如果沒有元素了將拋出 stopIteration 異常;
迭代器當然也可以用到 for 循環(huán)中;
迭代器實際上就是一種工廠模式。
迭代器和可迭代對象的區(qū)別
迭代器是迭代對象的一種,迭代器一定是可迭代對象,可迭代對象不一定是迭代器
一個合法的迭代器,必須同時實現(xiàn)iter和next兩個魔法方法
可迭代對象只需要實現(xiàn)iter方法即可
判斷對象 obj 可迭代的唯一方法就是調(diào)用 iter(obj),看返回結(jié)果是不是一個迭代器
每個迭代器的被迭代過程是一次性的,可迭代對象則不一定
生成器
特殊的迭代器,只需要使用 yield 關(guān)鍵字,那么就會立即變?yōu)橐粋€生成器,也就是說,只要一個函數(shù)中包含了一個 yield 關(guān)鍵字(不管幾個),那么這個函數(shù)就會自動變成一個生成器函數(shù);
生成器一定是一個迭代器,但反之不一定成立;
特點:
生成器中每次遇到 yield 關(guān)鍵字之后,會返回相應的結(jié)果;
保留函數(shù)當前的運行狀態(tài),等待下一次調(diào)用,下次調(diào)用時將從上一次返回 yield 語句處開始執(zhí)行后面的語句;
生成器的 send 方法可以向函數(shù)體內(nèi)去傳遞值;
對于 next 和 send 方法的異同:
next 和 send 都可以去調(diào)用一次生成器,從調(diào)用生成器的角度來說,他們的作用完全一樣;
next 無法像生成器內(nèi)部的變量賦值,但 send 可以;
next(gen) 等同于 send(None),可以互換;
在生成器中使用 for 循環(huán)
每一次 for 循環(huán)相當于調(diào)用一次 next;
for 循環(huán)會自動幫助我們處理 stopIteration 異常。
裝飾器
定義
裝飾器本質(zhì)是函數(shù),只是它的作用是為其他函數(shù)添加特定的附加功能;
編寫裝飾器的原則
裝飾器一定不能修改被裝飾器的函數(shù)的源碼;
裝飾器一定不能修改被裝飾的函數(shù)的調(diào)用方式;
實現(xiàn)裝飾器的前置知識條件
1.函數(shù)即變量
函數(shù)和普通變量的存儲原理是一樣的,函數(shù)名可以像變量名那樣去使用,比如可以進行賦值;
2.掌握高階函數(shù)相關(guān)知識
符合下面任意條件之一即為高階函數(shù)
條件一:接收函數(shù)名作為參數(shù)
條件二:返回值中包含函數(shù)名
3.掌握函數(shù)嵌套相關(guān)知識
通過 def 關(guān)鍵字在一個函數(shù) A 中去定義另外一個函數(shù) B,則函數(shù) B 稱為嵌套函數(shù);
4.裝飾器=高階函數(shù) + 嵌套函數(shù)
了解裝飾器的本質(zhì)優(yōu)勢
1.運行時校驗:在執(zhí)行階段進行特定校驗,當校驗不通過時終止執(zhí)行:
Django 框架中的用戶登錄態(tài)校驗裝飾器@login_required;
2.注入額外參數(shù):在函數(shù)被調(diào)用時自動注入額外的調(diào)用參數(shù):
unittest.mock 模塊的裝飾器@patch;
3.緩存執(zhí)行結(jié)果:通過調(diào)用參數(shù)等輸入信息,直接緩存函數(shù)執(zhí)行結(jié)果:
functools 模塊的緩存裝飾器@lru_cache;
4.注冊函數(shù):將被裝飾函數(shù)注冊為某個外部流程的一部分:
Flask 框架的路由注冊裝飾器@app.route;
5.替換為復雜對象:將原函數(shù) (方法) 替換為更復雜的對象,比如類實例或特殊的描述符對象:
靜態(tài)方法的裝飾器@staticmethod。
正則表達式
正則表達式匹配步驟:
1.import re
2.用 re.compile() 函數(shù)創(chuàng)建一個 Regex 對象(記得使用原始字符串)
3.向 Regex 對象的 search() 方法傳入想查找的字符串。它返回一個 Match 對象(一般用 mo 接收)
4.調(diào)用 Match 對象的 group() 方法,返回實際匹配的字符串
demo:
import re>>> phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')>>> mo = phoneNumRegex.search('my number is 415-555-4242.')>>> mo.group(1)'415'>>> mo.group(2)'555-4242'>>> mo.group()'415-555-4242'>>> mo.group(0)'415-555-4242'
PLus:
我在學習中,發(fā)現(xiàn)正則表達式在任何語言中都占有很大部分的占比,但正則表達式相關(guān)的知識點又過于零碎,對于榆木腦袋的我真是學一遍忘一遍。在實際工作中,我自己真正用到正則的地方并不多,再看同事,目前就發(fā)現(xiàn)前端同學有可能會用到正則去做一些事情,并且用到的時候都是度娘,一是自己真記不住,二是度娘 copy 過來的多數(shù)情況是比自己寫要嚴謹?shù)亩嗟摹?/span>
基于此,我把正則視為投入產(chǎn)出比太低的事情,僅需要記住個大概印象,真到用時能分清度娘上哪個輪子能用哪個輪子用不了就可以了。
測試基礎(chǔ)-Python篇 基礎(chǔ)②
常用模塊-math
import math
print(math.ceil(3.14)) # 取大于等于 x 的最小整數(shù)
print(math.fabs(-3)) # 取絕對值
print(math.floor(3.14)) # 取小于等于 x 的最大整數(shù)
print(math.fsum([1,2,3])) # 求和
print(math.pow(3,4)) #3 的 4 次方 等價于 3**4
print(math.sqrt(3)) # 開平方,3 的平方根
常用模塊-random
import random
print(random.random()) # 返回 [0.0,1.0) 之間的浮點數(shù)
print(random.randint(10,20)) # 生成 10 到 20 之間的一個隨機整數(shù),也就是 [10,20]
print(random.randrange(10,20)) # 生成 10 到 20 之間的一個隨機整數(shù),也就是 [10,20)
print(random.uniform(10,20)) # 生成 10 到 20 之間的一個隨機浮點數(shù),也就是 [10,20]
print(random.choice([10,20,30])) # 隨機從列表選擇一個數(shù)
print(random.choices([10,20,30],k=2)) # 隨機從列表選擇 k 個數(shù),返回列表形式,取出放回方式,意思是取出的數(shù)可以重復
print(random.sample(a1,3)) # 隨機從列表選 k 個數(shù),返回列表形式,取出不放回方式,意思是取出的數(shù)不會重復
random.shuffle(a1) # 洗牌,隨機變換列表順序
常用模塊-json
import jsond = {'name':'Tom','age':26}j = json.dumps(d)d2 = json.loads(j)print(d)print(type(d))print()print(j)print(type(j))print()print(d2)print(type(d2))-------------------------------------{'name': 'Tom', 'age': 26}<class 'dict'>
{'name': 'Tom', 'age': 26}
<class 'str'>
{'name': 'Tom', 'age': 26}
<class 'dict'>
常用模塊-time
import timen = time.time()print(n)n1 = round(n,3)print(n1)------------------------1675392067.29749661675392067.297
常用模塊-datetime()
import datetimedt = datetime.datetime.now()print(dt)print('dt.year:' + str(dt.year) + '---type:' + str(type(dt.year)))print('dt.month:' + str(dt.month) + '---type:' + str(type(dt.month)))print('dt.day:' + str(dt.day) + '---type:' + str(type(dt.day)))print('dt.hour:' + str(dt.hour) + '---type:' + str(type(dt.hour)))print('dt.minute:' + str(dt.minute) + '---type:' + str(type(dt.minute)))print('dt.second:' + str(dt.second) + '---type:' + str(type(dt.second)))----------------------------------------------------------------------------------------------------------2023-02-03 11:00:08.205691dt.year:2023---type:<class 'int'>
dt.month:2---type:<class 'int'>
dt.day:3---type:<class 'int'>
dt.hour:11---type:<class 'int'>
dt.minute:0---type:<class 'int'>
dt.second:8---type:<class 'int'>
import datetimeimport timenow = time.time()date = datetime.datetime.fromtimestamp(now)print(now)print(date)----------------------------------------------------------------------------1675393953.08603122023-02-03 11:12:33.086031
import datetimeimport timed1 = datetime.datetime.now()time.sleep(1)d2 = datetime.datetime.now()print(d2>d1)-----------------------------------------------True
import datetimeimport timed1 = datetime.datetime.now()time.sleep(1)d2 = datetime.datetime.now()d3 = d2 -d1print(d3)print(type(d3))------------------------------------------------0:00:01.002022<class 'datetime.timedelta'>
import datetimedt = datetime.timedelta(days=11,hours=10,minutes=9,seconds=8)print(dt)print(type(dt))print(dt.days)print(dt.seconds) # 天不參與計算,10*60*60 + 9*60 + 8 = 36548print(dt.total_seconds()) # 11*24*60*60 + 10*60*60 + 9*60 + 8 = 986948print(str(dt))---------------------------------------------------------------------------------------------------------11 days, 10:09:08<class 'datetime.timedelta'>
11
36548
986948.0
11 days, 10:09:08
import datetimedt = datetime.datetime.now()print(dt)thounsandDays = datetime.timedelta(days=1000)print(thounsandDays)print(dt + thounsandDays)------------------------------------------------------------------------------2023-02-06 14:20:46.2650841000 days, 0:00:002025-11-02 14:20:46.265084
常用模塊-logging
Logging 庫是非常常用的記錄日志庫,通過 logging 模塊存儲各種格式的日志,主要用于輸出運行日志,可以設(shè)置輸出日志的等級、日志保存路徑、日志文件回滾等;
import logginglogging.basicConfig(format='%(levelname)s %(asctime)s: %(message)s: %(module)s',level=logging.DEBUG)logging.debug('This message should appear on the console')logging.info('So should this')logging.warning('And this, too')-----------------------------------------------------------------------------------------------------DEBUG 2023-02-07 17:04:37,473: This message should appear on the console: logging_practiceINFO 2023-02-07 17:04:37,473: So should this: logging_practiceWARNING 2023-02-07 17:04:37,473: And this, too: logging_practice
import logginglogging.basicConfig(filename='myProgramLog',format='%(levelname)s %(asctime)s: %(message)s: %(module)s',level=logging.DEBUG)logging.debug('This message should appear on the console')logging.info('So should this')logging.warning('And this, too')
import logginglogging.disable(logging.CRITICAL)logging.basicConfig(filename='myProgramLog',format='%(levelname)s %(asctime)s: %(message)s: %(module)s',level=logging.DEBUG)logging.debug('This message should appear on the console')logging.info('So should this')logging.warning('And this, too')
常用模塊-threading
import timeimport threadingprint('Start of program.')def takeANap():
time.sleep(5)
print('Wake up!')threadObj = threading.Thread(target=takeANap)threadObj.start()print('End of program')----------------------------------------------------------------------------Start of program.End of programWake up!
注意:target 參數(shù)名后傳的是方法名,不加 (),因為此處并不是調(diào)用。
import threadingl = [1,2,3,4]def a(*args):
for _ in args:
print(_)thread_a = threading.Thread(target=a,args=l)thread_a.start()------------------------------------------------------------------------1234
import threadingd = {'name': 'Tom', 'age': 18}def b(**kwargs):
for k, v in kwargs.items():
print(str(k) + ':' + str(v))thread_b = threading.Thread(target=b, kwargs=d)thread_b.start()----------------------------------------------------------------------------name:Tomage:18
并發(fā)問題需要注意的是:為了避免并發(fā)問題,絕不讓多個線程讀取或?qū)懭胂嗤兞?。當?chuàng)建一個新的 Thread 對象時,要確保其目標函數(shù)只使用該函數(shù)中的局部變量。
線程阻塞-thread.join()
thread.join() 方法的作用是阻塞當前線程,直到調(diào)用 join() 方法的線程結(jié)束。也就是說,如果你有多個線程并希望在其中一個線程結(jié)束之后再繼續(xù)執(zhí)行,則可以使用 join() 方法。
# 不使用join,兩個線程并行運行import timeimport threadingdef a():
time.sleep(1)
print('我是a:1/3')
time.sleep(1)
print('我是a:2/3')
time.sleep(1)
print('我是a:3/3')def b():
print('我是b:1/2')
print('我是b:2/2')thread_a = threading.Thread(target=a)thread_b = threading.Thread(target=b)thread_a.start()thread_b.start()-------------------------------------------------------------我是b:1/2我是b:2/2我是a:1/3我是a:2/3我是a:3/3
# 使用join,線程b需要等線程a運行完后再運行import timeimport threadingdef a():
time.sleep(1)
print('我是a:1/3')
time.sleep(1)
print('我是a:2/3')
time.sleep(1)
print('我是a:3/3')def b():
print('我是b:1/2')
print('我是b:2/2')thread_a = threading.Thread(target=a)thread_b = threading.Thread(target=b)thread_a.start()thread_a.join()thread_b.start()--------------------------------------------------------------我是a:1/3我是a:2/3我是a:3/3我是b:1/2我是b:2/2
# join()方法可以自定義timeout參數(shù),意為最長暫用CPU時間,如果不設(shè)置的話就永遠等待;import timeimport threadingdef a():
time.sleep(1)
print('我是a:1/3')
time.sleep(1)
print('我是a:2/3')
time.sleep(1)
print('我是a:3/3')def b():
print('我是b:1/2')
print('我是b:2/2')thread_a = threading.Thread(target=a)thread_b = threading.Thread(target=b)thread_a.start()thread_a.join(timeout=2)thread_b.start()-------------------------------------------------------------我是a:1/3我是a:2/3我是b:1/2我是b:2/2我是a:3/3
深拷貝淺拷貝
不可變數(shù)據(jù)類型(如整型,字符串等)在 Python 中只是拷貝了值,因此在執(zhí)行淺拷貝時實際上是創(chuàng)建了一個新的副本,而不是拷貝引用。因此,對原數(shù)據(jù)的更改不會影響到拷貝后的數(shù)據(jù)。
import copya = 1000b = ac = copy.copy(a)d = copy.deepcopy(a)print(a, b, c, d)print(id(a), id(b), id(c), id(d))a += 1print(a, b, c, d)print(id(a), id(b), id(c), id(d))----------------------------------------------1000 1000 1000 10002518799374640 2518799374640 2518799374640 25187993746401001 1000 1000 10002518805613936 2518799374640 2518799374640 2518799374640
對于可變數(shù)據(jù)類型,淺拷貝只拷貝第一層中的引用,深拷貝在拷貝時,會逐層進行拷貝,直到所有的引用都是不可變對象為止。
import copya = [1, 2, [3, 4]]b = ac = copy.copy(a)d = copy.deepcopy(a)e = a.copy()f = a[:]print(a, b, c, d, e,f)print(id(a), id(b), id(c), id(d), id(e),id(f))print()a.append(5)print(a, b, c, d, e,f)print(id(a), id(b), id(c), id(d), id(e),id(f))print()a[2].append(6)print(a, b, c, d, e,f)print(id(a), id(b), id(c), id(d), id(e),id(f))----------------------------------------------------[1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]]2213595331584 2213595331584 2213595362304 2213595356992 2213595443008 2213595442368[1, 2, [3, 4], 5] [1, 2, [3, 4], 5] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]]2213595331584 2213595331584 2213595362304 2213595356992 2213595443008 2213595442368[1, 2, [3, 4, 6], 5] [1, 2, [3, 4, 6], 5] [1, 2, [3, 4, 6]] [1, 2, [3, 4]] [1, 2, [3, 4, 6]] [1, 2, [3, 4, 6]]2213595331584 2213595331584 2213595362304 2213595356992 2213595443008 2213595442368
Python 有多種方式實現(xiàn)淺拷貝,copy 模塊的 copy 函數(shù) ,對象的 copy 函數(shù) ,工廠方法,切片等。
賦值符號'=':如果是可變類型,就是引用傳遞;如果是不可變類型,就是值傳遞。
淺拷貝的優(yōu)點:拷貝速度快,占用空間少,拷貝效率高。
因為淺拷貝不能解決嵌套問題,所以引出了深拷貝,深拷貝會遍歷并拷貝 items 里所有的內(nèi)容 - 包括他嵌套的子列表;
對象的可哈希性
不可變的內(nèi)置類型都是可哈希的,比如 str、int、float、frozenset
可變的內(nèi)置類型都是不可以哈希的,比如 list、dict
對于不可變?nèi)萜黝愋停╰uple、frozenset),僅當他的所有成員都不可變時,他自身才是可哈希的
用戶定義的類型默認都是可哈希的
注意:只有可哈希對象才能被放進集合或者作為字典的鍵
sorted() 函數(shù)
sorted 函數(shù)是 Python 內(nèi)置函數(shù),用于對可迭代對象進行排序,并返回一個新的列表。
注意:sorted 函數(shù)不會改變原來的可迭代對象,而是返回一個新的列表。如果需要改變原來的可迭代對象,可以使用 sort 方法,但它只能用于列表。
參數(shù):
iterable:可以是列表、元組、字典等任意可迭代對象。
key:一個函數(shù),用于提取每個元素的排序關(guān)鍵字。默認為 None,表示按元素本身的順序進行排序。
reverse:是否按降序排列,默認為 False,表示按升序排列。
enumerate() 函數(shù)
enumerate() 適用于任何'可迭代對象',可以用于列表、元祖、字典、字符串等。
def enumerate_func():
names = ['lily','wenwen','tom']
for index, s in enumerate(names,start=1):
print(index,s)---------------------------------------------1 lily2 wenwen3 tom
如果不指定 start 參數(shù),則 index 從 0 開始
測試基礎(chǔ)-Python篇 基礎(chǔ)③
浮點數(shù)精度問題
print(0.1+0.2)----------------------0.30000000000000004
可以使用 decimal 模塊解決浮點數(shù)精度問題:
from decimal import Decimalprint(Decimal('0.1') + Decimal('0.2'))print(type(Decimal('0.1') + Decimal('0.2')))print(type(Decimal('0.1')))---------------------------------------------------------0.3<class 'decimal.Decimal'>
<class 'decimal.Decimal'>
注意:在使用 Decimal 時要用字符串來表示數(shù)字
布爾值其實也是數(shù)字
def sum_even(numbers: list[int]):
'''
返回numbers中偶數(shù)的個數(shù)
:param numbers: 整數(shù)列表
'''
return sum(i % 2 == 0 for i in numbers)
不常用但特別好用的字符串方法
s = 'TomAndMarry's2 = s.partition('And')print(s2)--------------------------------('Tom ', 'And', ' Marry')
s = '明明是中文,卻使用了英文標點.'table = s.maketrans(',.', ',。')s2 = s.translate(table)print(s2)-----------------------------------------------明明是中文,卻使用了英文標點。
使用枚舉類型來替代字面量
# 用戶每日獎勵積分數(shù)量DAILY_POINTS_REWARDS = 100# VIP用戶額外獎勵20VIP_EXTRA_POINTS = 20from enum import Enumclass UserType(int, Enum):
# VIP用戶 VIP = 3
# 小黑屋用戶 BANNED = 13def add_daily_points(user):
'''用戶每天第一次登錄增加積分'''
if user.type == UserType.BANNED:
return
if user.type == UserType.VIP:
user.points += DAILY_POINTS_REWARDS + VIP_EXTRA_POINTS
return
user.points += DAILY_POINTS_REWARDS
return
生成器
定義一個生成器需要生成器函數(shù)和 yield 關(guān)鍵字
yield 和 return 最大的區(qū)別在于,return 會一次性返回結(jié)果,使用它會直接中斷函數(shù)執(zhí)行,而 yield 可以逐步給調(diào)用方生成結(jié)果
使用生成器的優(yōu)點是它們占用的內(nèi)存比列表要少,因為它們只生成一個元素并在需要時生成下一個元素。這使得生成器特別適合于處理大量數(shù)據(jù)
每次調(diào)用生成器函數(shù)都會生成一個新的生成器對象
fruits = {'apple','orange','pineapple'}def batch(item):
for _ in item:
yield _print(next(batch(fruits)))print(next(batch(fruits)))print(next(batch(fruits)))---------------------------------------appleappleapple
因為每次調(diào)用生成器函數(shù)都會生成一個新的生成器對象,所以以上程序運行結(jié)果會輸出三個 apple
fruits = {'apple','orange','pineapple'}def batch(item):
for _ in item:
yield _g = batch(fruits)print(next(g))print(next(g))print(next(g))-------------------------------------------------pineappleappleorange
以上代碼再次驗證了'每次調(diào)用生成器函數(shù)都會生成一個新的生成器對象'結(jié)論
def batch_process(item):
result = []
for i in item:
# process_item = ..處理item result.append(process_item)
return result# 以上方法會有一個問題,當item過大時,會導致函數(shù)執(zhí)行很耗時,并且若調(diào)用方想在某個process_item達到條件時中斷,以上方法也是做不到的。所以可以使用生成器函數(shù)替代。def batch_process_2(item):
for i in item:
# process_item = ..處理item yield process_item# 調(diào)用方for processed_item in batch_process_2(items):
# 如果某個處理對象過期了,就中斷當前的所有處理 if processed_item.has_expired():
break
面向?qū)ο缶幊?/strong>
內(nèi)置類方法裝飾器
類方法
1.用 def 在類里定義一個函數(shù)時,這個函數(shù)通常被稱作方法。調(diào)用這個方法需要先創(chuàng)建一個類實例;
2.可以使用@classmethod裝飾器定義類方法,它屬于類,無需實例化也能調(diào)用;
3.作為一種特殊方法,類方法最常見的使用場景,就是定義工廠方法來生成新實例,類方法的主角是類型本身,當發(fā)現(xiàn)某個行為不屬于實例,而是屬于整個類型是,可以考慮使用類方法;
靜態(tài)方法
1.如果發(fā)現(xiàn)某個方法不需要使用當前實例里的任何內(nèi)容,那可以使用@staticmethod來定義一個靜態(tài)方法;
2.和普通方法相比,靜態(tài)方法不需要訪問實例的任何狀態(tài),是一種與狀態(tài)無關(guān)的方法,因此靜態(tài)方法其實可以寫成脫離于類的外部普通函數(shù);
2.1.如果靜態(tài)方法特別通用,與類關(guān)系不大,那么把他改成普通函數(shù)會更好;
2.2.如果靜態(tài)方法與類關(guān)系密切,那么用靜態(tài)方法更好;
2.3.相比函數(shù),靜態(tài)方法有一些先天優(yōu)勢,比如能被子類繼承和重寫;
屬性裝飾器
1.@property 裝飾器模糊了屬性和方法間的界限,使用它,可以把方法通過屬性的方式暴露出來;
2.@property 除了可以定義屬性的讀取邏輯外,還支持自定義寫入和刪除邏輯;
class FilePath:
@property
def basename(self):
....
@property.setter
def basename(self, name):
....
@property.deleter
def basename(self):
....
經(jīng)過@property的裝飾以后,basename 已經(jīng)從一個普通的方法變成了 property 對象,所以可以使用 basename.setter 和 basename.deleter 方法;
定義 setter 方法,該方法會在對屬性賦值是被調(diào)用;
定義 deleter 方法,該方法會在刪除屬性時被調(diào)用;
鴨子類型及其局限性
抽象類
isinstance() 函數(shù)
利用 isinstance() 函數(shù),我們可以判斷對象是否屬于特定類型;
isinstance() 函數(shù)能理解類之間的繼承關(guān)系,因此子類的實例同樣可以通過基類的校驗;
校驗對象是否是 Iterable 類型
在 collections.abc 模塊中,有許多和容器相關(guān)的抽象類,比如代表集合的 Set、代表序列的 Sequence 等,其中有一個最簡單的抽象類:Iterable,他表示的是可迭代類型;
鴨子類型和抽象類總結(jié)
鴨子類型是一種編碼風格,在這種風格下,代碼只關(guān)心對象的行為,不關(guān)心對象的類型;
鴨子類型降低了類型校驗的成本,讓代碼變得更靈活;
傳統(tǒng)的鴨子類型里,各種對象接口和協(xié)議都是隱式的,沒有統(tǒng)一的顯示標準;
傳統(tǒng)的 isinstance() 類型檢查和鴨子類型的理念是相違背的;
抽象類是一種特殊的類,他可以通過鉤子方法來定制動態(tài)的子類檢查行為;
因為抽象類的定制子類化特征,isinstance() 也變得更靈活、更契合鴨子類型了;
使用@abstractmethod裝飾器,抽象類可以強制要求子類在繼承時重寫特定方法;
除了抽象方法外,抽象類也可以實現(xiàn)普通的基礎(chǔ)方法,供子類繼承使用;
在 collections.abc 模塊中,有許多與容器相關(guān)的抽象類;
多重繼承于MRO
學習建議
對于Python入門及進階,我推薦兩本我認為值得多次閱讀的書籍:
for......else......的執(zhí)行順序:
當?shù)鷮ο笸瓿伤械笄掖藭r的迭代對象為空時,如果存在 else 子句則執(zhí)行 else 子句,沒有則繼續(xù)執(zhí)行后續(xù)代碼;如果迭代對象因為某種原因(如帶有 break 關(guān)鍵字)提前退出迭代,則 else 子句不會被執(zhí)行,程序?qū)苯犹^ else 子句繼續(xù)執(zhí)行后續(xù)代碼;
數(shù)值型比較不能使用 not in,因為 not in 本質(zhì)是循環(huán)遍歷右側(cè)數(shù)據(jù),用左側(cè)數(shù)據(jù)進行比對,len() in range(1,5) 可以使用,因為 range 是一個集合,可以遍歷, 'li' in 'lili'不建議使用,因為返回結(jié)果為 True(包含),達不到預期結(jié)果,所以準確比較建議使用'==';
字典取值:有兩種方式,a={'name':'lili'}
第一種:a['name']
第二種:a.get('name')
區(qū)別:a['wenwen'] 報錯-KeyError a.get('wenwen') 不報錯-None
如果在方法中給全局變量賦值,則要在方法中提前聲明全局變量-global;
列表轉(zhuǎn)成字符串''.join(list)
用''中的字符串作為連接,拼接 list 列表中的每個元素 --- 只能用在每個元素都是字符串的時候可以用,要不然就會報錯;
集合數(shù)據(jù)類型 set 取值
因為集合(set)是一種無序的不重復的元素的集合。因為集合中的元素沒有特定的順序,所以無法通過下標索引來訪問。
可以使用循環(huán)遍歷取值,也可使用 in 判斷目標元素是否在集合中。
當遇到復雜計算的數(shù)字字面量時,保留整個數(shù)學公式,提示可讀性也不會降低性能;
要判斷某個容器是否包含特定成員,用集合比用列表更合適,因為集合底層使用了哈希表數(shù)據(jù)結(jié)構(gòu)
# 列表數(shù)據(jù)越多效果越明顯VALID_NAMES = ['pip', 'lili', 'name']VALID_NAMES_SET = set(VALID_NAMES)def validate_name(name):
if name not in VALID_NAMES_SET:
raise ValueError(f'{name} is not a valid name')
nums = [10, 2, 3, 21, 10, 3]def ordered_dict(member: list[int]):
from collections import OrderedDict
result = list(OrderedDict.fromkeys(member).keys())
return resultprint(ordered_dict(nums))----------------------------------------------------[10, 2, 3, 21]
from typing import NamedTupleclass Address(NamedTuple):
'''地址信息結(jié)果'''
country: str
province: str
city: strdef latlon_to_address(lat, lon):
return Address(
country = country,
province= province,
city = city,
)addr = latlon_to_address(lat, lon)# 通過屬性名來使用addr
# addr.city / addr.country / addr.province
from itertools import productprint(list(product([1,2],[3,4])))----------------------------------------[(1, 3), (1, 4), (2, 3), (2, 4)]
# 常用多層嵌套循環(huán)def find_twelve(nem_list1, num_list2, num_list3):
'從這三個數(shù)字列表中,尋找是否存在和為12的3個數(shù)'
for num1 in num_list1:
for num2 in num_list2:
for num3 in num_list3:
if num1 + num2 + num3 == 12:
return num1, num2, num3# 使用product()扁平化多層嵌套循環(huán)from itertools import productdef find_tewlve_v2(num_list1, num_list2, num_list3):
for num1, num2, num3 in product(num_list1, num_list2, num_list3):
if num1 + num2 + num3 == 12:
return num1, num2, num3
# 方法1:使用enumeratedef parse_titles(filename):
'''從各行數(shù)據(jù)文件中取數(shù)據(jù)'''
with open(filename, 'r') as fp:
for i, line in enumerate(fp):
if i % 2 == 0:
yield lineif __name__ == '__main__':
message_generator = parse_titles('logs.txt')
while True:
try:
print(next(message_generator))
except StopIteration as e:
break
但如果需求變更為每隔3行讀取或者每隔4行讀取,那我們按照以上的寫法應該怎么篩選呢?
# 方法2:使用islicefrom itertools import islicedef parse_titles_v2(filename):
'''使用slice實現(xiàn)隔行取值'''
with open(filename, 'r') as fp:
for line in islice(fp, 0, None, 2): # islice(seq, start, end, step) yield lineif __name__ == '__main__':
message_generator = parse_titles_v2('logs.txt')
while True:
try:
print(next(message_generator))
except StopIteration as e:
break
如果需求變更為每隔3行讀取或者每隔4行讀取,我們只需要將 islice(seq, start, end, step) 中的 step 改成3或者4就行了

面對洋洋灑灑的知識點,我往往 “一看就會,一寫就廢”,為了更有針對性的加深知識點的印象,接下來,我將以做題的形式繼續(xù)總結(jié)Python系列,如果有不正確的地方,希望各位佬兒哥指正糾偏:
1.列表的增刪查改?
增
l.insert(idx, value) ---指定索引位置增加
l.append(value) ---在末尾追加
l.extend(iterable) ---取出可迭代對象的值,追加到列表末尾
l1 = [1,2,3,3,4,5]l1.extend([1,[2]])print(l1)--------------------------[1, 2, 3, 3, 4, 5, 1, [2]]
刪
del l[idx] ---刪除索引處元素,索引超出會報錯:IndexError: list assignment index out of range
del l ---徹底刪除列表
l.pop(idx) ---刪除索引處元素,索引超出會報錯:IndexError: pop index out of range
l.pop() ---刪除列表最后一個元素,列表為空會報錯:IndexError: pop from empty list
l.remove(value) ---刪除列表中第一個出現(xiàn) value 的元素,值不在會報錯:ValueError: list.remove(x): x not in list
l.clear() --清除列表中的所有元素
查
l[idx]
l.count(value) ---統(tǒng)計列表中指定元素出現(xiàn)次數(shù),指定元素不在列表中會返回:0
l.index(value) ---返回列表中第一個指定元素的索引,指定元素不在列表中會報錯:ValueError: 11 is not in list
改
l[idx] = value
2.字典的增刪查改?
增
d[new_key] = value ---如果 key 已存在則是更新操作
d.update({key: value}) ---如果 key 存在則是更新操作
d = dict.fromkeys(keys, value) ---dict.fromkeys(keys, value) 方法用于創(chuàng)建一個新字典,其中包含指定的鍵,并將所有鍵的值設(shè)置為相同的值
d.setdefault(key, default_value) ---如果 key 已存在,則返回對應的 value,若 key 不存在,則返回 default_value,并在原字典中新增鍵值對 key: default_value
# 可用setdefault()統(tǒng)計每個單詞的出現(xiàn)次數(shù)text = 'Hello world! Hello python! Hello chatbot!'word_list = text.split()word_count = {}for word in word_list:word_count[word] = word_count.setdefault(word, 0) + 1print(word_count)--------------------------------------------------------------------------------------------{'Hello': 3, 'world!': 1, 'python!': 1, 'chatbot!': 1}
刪
d.pop(key) ---key 不存在會報錯:KeyError: 'addr'
d.popitem() ---隨機刪除一個鍵值對,因為字典無序,所以是隨機刪除,字典為空則報錯:KeyError: 'popitem(): dictionary is empty'
del d[key] ---刪除指定 key,若 key 不存在則報錯:KeyError: 'addr'
del d ---徹底刪除字典
d.clear ---清空字典
查
d[key] ---若 key 不存在則報錯:KeyError: 'addr'
d.get(key) ---若 key 不存在則返回 None
d.keys() ---以列表形式返回字典的所有 key
d.values() ---以列表的形式返回字典的所有 value
d.items() --以列表的形式返回字典的所有鍵值對,每一組鍵值對是一組元祖
d1 = {'name': 'Tom', 'age': 25}print(d1.keys())print(type(d1.keys()))print()print(d1.values())print(type(d1.values()))print()print(d1.items())print(type(d1.items()))------------------------------------------------dict_keys(['name', 'age'])<class 'dict_keys'>
dict_values(['Tom', 25])
<class 'dict_values'>
dict_items([('name', 'Tom'), ('age', 25)])
<class 'dict_items'>
d[key] = value
d1.update(d2) ---將 d2 更新到 d1 中,相同的 key 則更改 d1 中的 value
3.元祖的增刪查改
因為元祖是不可變數(shù)據(jù)類型,所以不能不能在原元祖新增
t = (1,2,'hello')t2 = (2,3,'world')print(id(t))t += t2print(t)print(id(t))-------------------------2049302192960(1, 2, 'hello', 2, 3, 'world')2049302145920
del t ---不能 del t[idx],否則報錯:TypeError: 'tuple' object doesn't support item deletion
t[idx] ---idx 不能越界,否則報錯:IndexError: tuple index out of range
可遍歷元祖
for _ in t:
print(_)
t.count(value) ---返回元祖中 value 的個數(shù),value 不存在返回 0
t.index(value) ---返回元祖中首個 value 的索引,value 不存在則報錯:ValueError: tuple.index(x): x not in tuple
元組是不可變的,因此不能修改元組中的任何元素。
4.例舉Python6種基本的數(shù)據(jù)類型,并標出哪些是不可變數(shù)據(jù)類型?
整形-int-不可變、浮點型-float-不可變、字符型-str-不可變、列表-list-可變、元祖-tuple-不可變、字典-dict-可變
5.請說明循環(huán)結(jié)構(gòu)和異常處理中的 else 在什么情況下會執(zhí)行?
在 for.else 循環(huán)結(jié)構(gòu)中,當循環(huán)提全部循環(huán)完畢后,沒有 break 或者 return 的情況下,會執(zhí)行 else 代碼段;
在異常處理中,try 下的代碼段沒有出現(xiàn)異常的情況下,會執(zhí)行 else 代碼
條件分支語句用 else 來表示'否則執(zhí)行某件事'
6.列舉python函數(shù)定義中有哪些不同的參數(shù)類型?
1.位置參數(shù):根據(jù)參數(shù)在函數(shù)定義中的位置來確定。
2.默認參數(shù):在函數(shù)定義中指定的參數(shù)值。
3.關(guān)鍵字參數(shù):在調(diào)用函數(shù)時指定參數(shù)名稱和對應的值。
4.星號參數(shù):在函數(shù)定義中使用來捕獲剩余的參數(shù)。
5.雙星號參數(shù):在函數(shù)定義中使用* 來捕獲剩余的關(guān)鍵字參數(shù)。
7.python中==和is的區(qū)別?
==比較的是兩個對象的值,is 比較的是兩個對象的內(nèi)存地址。
不能用 is 替代==,僅當你需要判斷某個對象是否是 None、False、True 時,使用 is,其他情況下請使用==。
a = [1,2,3]b = [1,2,3]print(id(a))print(id(b))print(a == b)print(a is b)--------------------22782856545922278285654272TrueFalse
a = [1,2,3]b = aprint(id(a))print(id(b))print(a == b)print(a is b)---------------------20215765550722021576555072TrueTrue
額外:關(guān)于賦值或者復制后 id() 是否異同的知識點,結(jié)論:除了'='賦值,其余的 id() 都不一樣,直接舉例:
import copya = [1,2,3]b = ac = a.copy()d = copy.copy(a)e = copy.deepcopy(a)f = a[:]print(id(a))print(id(b))print(id(c))print(id(d))print(id(e))print(id(f))------------------192714345516819271434551681927140937408192714093715219271435578241927143558528
8.請描述global關(guān)鍵字在什么條件下必須被使用?
在函數(shù)局部要重新賦值全局變量之前,需要使用 global 關(guān)鍵字聲明全局變量。
9.請說明if name == 'main':語句的作用?
在 Python 中,當一個模塊被執(zhí)行時,if name == 'main':語句塊會被執(zhí)行。此語句塊可以用來測試模塊的代碼,而不會影響模塊的其他功能。
如果模塊被其他模塊導入,則name的值為該模塊的名稱,而不是main。如果該模塊是主程序,則name的值為main,此時該語句塊會被執(zhí)行。
這樣的語句使得可以在模塊被其他模塊導入時忽略測試代碼,并且只在模塊被獨立運行時執(zhí)行測試代碼。
10.面向?qū)ο缶幊逃心娜筇匦??請說明各個特性的意義。
封裝:隱藏內(nèi)部狀態(tài)和實現(xiàn)細節(jié),僅提供必要的接口給外部使用。
繼承:允許創(chuàng)建新的對象類型,并基于現(xiàn)有的對象類型派生,從而繼承其行為和狀態(tài)。
多態(tài):允許不同類型的對象對相同消息做出不同的響應。
11.類反射中常用的方法及含義?
常用的類反射方法有:
type(object):獲取對象的類型,返回一個 type 對象。
isinstance(object, classinfo):判斷對象是否是某種類型的實例,返回布爾值。
issubclass(class, classinfo):判斷一個類是否是另一個類的子類,返回布爾值。
getattr(object, name[, default]):獲取對象的屬性或方法,如果不存在,可以返回 default 參數(shù)指定的默認值。
hasattr(object, name):判斷對象是否具有某個屬性或方法,返回布爾值。
setattr(object, name, value):設(shè)置對象的屬性值。
delattr(object, name):刪除對象的屬性。
使用類反射可以動態(tài)地獲取和操作類的信息,是動態(tài)語言的重要特性。
12.python中創(chuàng)建一個新線程有哪幾種方式?
1.使用 threading 模塊:通過定義一個繼承自 Thread 的類并重寫其 run 方法,然后通過該類的實例調(diào)用 start 方法啟動線程。
2.使用 multiprocessing 模塊:通過使用 Process 類創(chuàng)建新的進程。
3.使用協(xié)程:通過使用生成器實現(xiàn)協(xié)程,在協(xié)程內(nèi)部通過 yield 實現(xiàn)非阻塞的多任務(wù)執(zhí)行。
多線程編程是高并發(fā)編程的一種常見形式,可以提高程序的執(zhí)行效率。
13.python中GIL全局解釋器鎖在什么情況下會被釋放?
Python 中的 GIL (Global Interpreter Lock) 是一種機制,它限制任意時刻僅有一個線程可以運行在 Python 解釋器中。GIL 在以下情況下會被釋放:
解釋器在執(zhí)行 CPU 密集型任務(wù)時:例如運算,在這種情況下,GIL 會每隔一定時間被釋放,以便其他線程有機會被調(diào)度執(zhí)行。
解釋器在執(zhí)行 I/O 密集型任務(wù)時:例如讀取文件,在這種情況下,由于 I/O 操作需要等待外部設(shè)備,所以 GIL 會在 I/O 操作期間被釋放。
GIL 可能會影響多線程程序的性能,因此通常不建議在 Python 中開發(fā) CPU 密集型的多線程程序??梢允褂枚噙M程來代替多線程以提高性能。
14.描述編寫裝飾器的原則是什么?
1.不改變原函數(shù)的內(nèi)部邏輯
2.不改變原函數(shù)的調(diào)用方法
15.現(xiàn)在有一個Animal類有初始化方法定義如下:
class Animal:
def init(self, skin, legs):
self.skin = skin
self.legs = legs
如果現(xiàn)在想定義一個Dog類,并繼承于這個Animal類,并想給這個Dog類增加一個nickname對象屬性,Dog類的初始化方法應該怎么定義才能保證 Dog 類和其父類均能初始化成功?
# 兩種寫法,第二種以Cat舉例class Animal:
def __init__(self, skin, legs):
self.skin = skin
self.legs = legsclass Dog(Animal):
def __init__(self, skin, legs, nickname):
super().__init__(skin, legs)
self.nickname = nicknameclass Cat(Animal):
def __init__(self, skin, legs, hobby):
Animal.__init__(self, skin, legs)
self.hobby = hobbya = Animal(skin='sss', legs='lll')d = Dog(skin='sss', legs='lll', nickname='nnn')c = Cat(skin='sss', legs='lll', hobby='hhh')print(a.skin)print(d.nickname)print(c.hobby)print(c.skin)----------------------------------------------------------------------sssnnnhhhsss
super 方法是 Python 中的一種特殊方法,用于引用父類。它常用于多重繼承,當子類需要調(diào)用父類的方法時,就可以使用 super 方法。這個方法可以直接調(diào)用父類的方法,而無需顯式命名父類名稱。
16.文件zen.txt中保存著python之禪,請使用python代碼統(tǒng)計該文件中每個單詞出現(xiàn)的次數(shù)。
file_path = r'C:\Users\EDZ\Desktop\zen.txt'with open(file_path, 'r') as f:
text = f.read()words = text.split()word_counts = {}for word in words:
if word in word_counts:
word_counts[word] += 1
else:
word_counts[word] = 1print(word_counts)
17.編寫一個裝飾器,使用該裝飾器能夠顯示任意函數(shù)運行所需時間。
def running_time(fun):
def wrapper(*args, **kwargs):
start_time = time.time()
result = fun(*args, **kwargs)
end_time = time.time()
print(f'{fun.__name__}運行花費了:{end_time-start_time:.2f} 秒。')
return result
return wrapper@running_timedef take_time():
time.sleep(2)take_time()----------------------------------------------------take_time運行花費了:2.01 秒。
18.用兩種方法合并下面列表
x = ['a', 'b']y = ['c', 'd', 'e']x.extend(y)# 或x += y
19.計算得到列表當中長度最長的字符串words = ['Python', 'is', 'awesome']
words = ['Python', 'is', 'awesome']# 我的笨方法s = ''for _ in words:
if len(_) > len(s):
s = _print(s)# 標答給的方法
# 使用內(nèi)置函數(shù) max() 和 len() 計算,在 max() 函數(shù)中使用 key 參數(shù)指定了用于比較大小的函數(shù)為 len(),這樣比較的就是字符串的長度,而不是字典序。longest_word = max(words, key=len)print(longest_word)
20.將列表中的順序倒轉(zhuǎn) (2 種方法) words = ['Python', 'is', 'awesome']
words = ['Python', 'is', 'awesome']# 方法1,列表的reverse()方法(改變原列表)words.reverse()print(words)# 方法2,列表切片(生成新列表,原列表不變)w = words[::-1]print(w)
21.將字典當中的鍵值對位置調(diào)換
staff = {'Data Scientist': 'Mike', 'Django Developer': 'Dylan'}
答:
staff = {'Data Scientist': 'Mike', 'Django Developer': 'Dylan'}# 我的笨方法reverse = {}for k, v in staff.items():
reverse[v] = kprint(reverse)# 標答給的方法(字典推導式)inverted_staff = {v: k for k, v in staff.items()}print(inverted_staff)
22.將嵌套列表合并為一個列表
l = [[1, 2, 3], [4, 5], [6], [7, 8], [9]]
答:
# 針對此題目,我想到的是循環(huán)遍歷result = []for i in l:
for n in i:
result.append(n)print(result)# 標答給的方法1:
# 在 sum() 函數(shù)中使用的第二個參數(shù)是空列表,表示從空列表開始計算和。merged_list = sum(l, [])print(merged_list) # 標答給的方法2:列表推導式merged_list = [item for sublist in l for item in sublist]print(merged_list)# 可如上3個方法只能針對此題目,一旦題目列表沒這么規(guī)范,比如下面的列表,那么如上3個方法就無法實現(xiàn)l = [0, [1, 2, [3]], [4, 5], [6], [7, 8], [9]]# 能夠同時解決如上問題的方法是使用遞歸函數(shù)def flatten_list(l):
flat_list = []
for item in l:
if type(item) == list:
flat_list.extend(flatten_list(item))
else:
flat_list.append(item)
return flat_listprint(flatten_list(l))
23.列表當中數(shù)據(jù)類型的轉(zhuǎn)換
我們要將其轉(zhuǎn)換成整數(shù)類型====>['1', '2', '3']
我們要將其轉(zhuǎn)換成浮點數(shù)類型====>['1', 2, '3.0', 4.0, '5', 6]
答:
l = ['1', '2', '3']l1 = [int(i) for i in l]print(l1)l2 = ['1', 2, '3.0', 4.0, '5', 6]l3 = [float(i) for i in l2]print(l3)
24.將列表轉(zhuǎn)化成字典
cars = ['Audi', 'BMW', 'Ford', 'Tesla', 'Volvo']
答:
cars = ['Audi', 'BMW', 'Ford', 'Tesla', 'Volvo']d = dict.fromkeys(cars, 0)print(d)
25.將列表當中的重復元素去除
['a', 'a', 'b', 'a', 'c']
答:
l = ['a', 'a', 'b', 'a', 'c']l1 = list(set(l))print(l1)
26.從列表中篩選出特定元素 (2種方法)
cars = ['Audi', 'BMW', 'Ford', 'Tesla', 'Volvo']
答:
cars = ['Audi', 'BMW', 'Ford', 'Tesla', 'Volvo']# 我想到的是列表推導式l = [i for i in cars if i == 'Volvo']print(l)# 標答使用filterl2 = filter(lambda car: car == 'Volvo', cars)print(list(l2))# filter 函數(shù)在 Python 中返回一個過濾器對象,它是一個迭代器,所以想打印值需要使用list()
27.列表中的元素排序
numbers = [55, -30, 28, -36, 48, 20]
cars = ['Ford', 'Tesla', 'BMW', 'Volvo', 'Audi']
答:
numbers.sort()print(numbers)cars.sort()print(cars)
28.合并集合
set1 = {'1', '2', '5'}
set2 = {'4', '6', '7'}
答:
set1.update(set2)print(set1)
29.根據(jù)鍵來對字典進行排序
d = {'one': 1, 'three': 4, 'five': 8, 'six': 10, 'two': 2}
答:
sorted_dict = sorted(d.items(), key=lambda x: x[0])print(sorted_dict)
30.根據(jù)鍵值來對字典進行排序
d = {'one': 1, 'three': 4, 'five': 8, 'six': 10, 'two': 2}
答:
sorted_dict = sorted(d.items(), key=lambda x: x[1])print(sorted_dict)
31.替換字符串
s = 'Python is a programming language. Python is awesome'# 字符類型是不可變數(shù)據(jù)類型,str.replace()方法不會改變原字符串,會生成新值ss = s.replace('P','p')print(ss)
32.計算指定字符串出現(xiàn)的次數(shù)
a = 'python is a programming language. python is python.'
答:
# 我得笨方法:d = {}for _ in a:
if _ not in d:
d[_] = 1
else:
d[_] += 1print(d['p'])# 標答print(a.count('p'))
33.將矩陣轉(zhuǎn)置
a = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
答:
b = [list(s) for s in zip(*a)]print(b)
34.生成斐波那契數(shù)列
斐波那契數(shù)列是一個數(shù)列,其中的每個數(shù)都是前兩個數(shù)的和。
答:
def fibonacci(n):
if n <= 0:
return []
elif n == 1:
return [0, ]
elif n == 2:
return [0, 1]
else:
fib = [0, 1]
for i in range(2, n):
fib.append(fib[-1] + fib[-2])
return fibprint(fibonacci(10))-----------------------------------------------------[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
35.冒泡排序
def bubble(l):
for i in range(len(l) - 1):
for j in range(len(l) - 1 - i):
if l[j] > l[j + 1]:
l[j], l[j + 1] = l[j + 1], l[j]
return l
36.Python的解包是什么?
解包是 Python 里的一種特殊賦值語句,可以把可迭代對象 (列表,元祖,字典,字符串) 一次性賦給多個值。
a, b, c = (1, 2, 3)
a, b = b, a
numbers = [1, 2, 3, 4, 5]for a, b in zip(numbers, numbers[1:]):
print(a, b)---------------------------------------------------------1 22 33 44 5
注意:
37.有一個key為姓名,value為年齡的字典,根據(jù)年齡正序排列姓名,并輸出姓名列表,若沒有年齡,則放在最后;
users = {'tom': 19, 'jerry': 13, 'jack': None, 'andrew': 43}
答:
知識點:在排序前將年齡為 None 的值變更為正無窮大;
正無窮:float('inf')
負無窮:float('-inf')
# 我想到的方法:
# 先將字典中年齡為None的值變更成正無窮大def key_func(users):
for key in users.keys():
if users[key] is None:
users[key] = float('inf')# 根據(jù)年齡進行正序排序,最后以列表形式輸入排序好的姓名def sort_user(user: dict):
sort_item_for_v = sorted(user.items(), key=lambda x: x[1])
return [user[0] for user in sort_item_for_v]key_func(users)print(sort_user(users))-------------------------------------------------------------------------------['jerry', 'tom', 'andrew', 'jack']
# 參考答案:def sort_user_inf(users: dict):
'''
接收一個key為姓名,value為年齡的字典,根據(jù)年齡正序排列姓名,若沒有年齡,則放在最后
:param users: 用戶名:年齡字典
:return: 返回姓名列表
'''
def key_func(username):
age = users[username]
# 當年齡為空時,返回正無窮大作為key,因此就會被排到最后 return age if age is not None else float('inf')
return sorted(users.keys(), key=key_func)print(sort_user_inf(users))-----------------------------------------------------------------------------['jerry', 'tom', 'andrew', 'jack']
38.合并字典的多種方式?
d1 = {'name': 'Lili', 'score': 90}d2 = {'name': 'Tom', 'hobby': 'run'}d1.update(d2)print(d1)-----------------------------{'name': 'Tom', 'score': 90, 'hobby': 'run'}# 這種方法會改變d1的原始值
d1 = {'name': 'Lili', 'score': 90}d2 = {'name': 'Tom', 'hobby': 'run'}def update_dict(d1: dict, d2: dict):
d = d1.copy()
d.update(d2)
return dprint(update_dict(d1,d2))print(d1)print(d2)---------------------------------------{'name': 'Tom', 'score': 90, 'hobby': 'run'}{'name': 'Lili', 'score': 90}{'name': 'Tom', 'hobby': 'run'}
d1 = {'name': 'Lili', 'score': 90}d2 = {'name': 'Tom', 'hobby': 'run'}print({**d1, **d2})print({**d2, **d1})print(d1)print(d2)--------------------------------------{'name': 'Tom', 'score': 90, 'hobby': 'run'}{'name': 'Lili', 'hobby': 'run', 'score': 90}{'name': 'Lili', 'score': 90}{'name': 'Tom', 'hobby': 'run'}
d1 = {'name': 'Lili', 'score': 90}d2 = {'name': 'Tom', 'hobby': 'run'}print(d1|d2)print(d2|d1)print(d1)print(d2)-----------------------------{'name': 'Tom', 'score': 90, 'hobby': 'run'}{'name': 'Lili', 'hobby': 'run', 'score': 90}{'name': 'Lili', 'score': 90}{'name': 'Tom', 'hobby': 'run'}
39.json和Python中的dict有什么區(qū)別?
1.JSON 的類型是字符串,字典的類型是 dict;
2.JSON 的 key 只能是字符串,字典的 key 可以是任何可 hash 對象,如:字符串,數(shù)字,元祖;
3.JSON 的 key 是有序的,可以重復的;字典的 key 不能重復;
4.JSON 的 key 有默認值 undefined,字典的 key 默認沒有默認值;
5.JSON 的 value 可以是字符串、浮點數(shù)、布爾值、null 或者他們組成的數(shù)組或?qū)ο螅值涞?value 可以是任意類型的對象;
6.JSON 的 value 訪問方式可以是 [] 或者.,字典的 value 訪問方式只能是 key 值;
7.JSON 的字符串強制使用雙引號,字典的字符串可以是單引號也可以是雙引號;
8.字典可以嵌套元祖,JSON 只有數(shù)組;
9.真假空的表示:JSON(true,false,null),字典(True,F(xiàn)alse,None);
10.JSON 的中文必須是 Unicode 編碼,如'\u6211'。
40.Python列表和字符串的相互轉(zhuǎn)換?
第一種類型:
s = '1,2,3,4,5'l = s.split(',')print(l)l2 = [int(i) for i in l]print(l2)--------------------['1', '2', '3', '4', '5'][1, 2, 3, 4, 5]
第二種類型:
l1 = ['1','2','3']s1 = ','.join(l1)print(s1)---------------1,2,3
第三種類型:
l2 = [1,2,3]s2 = ','.join([str(i) for i in l2])print(s2)-----------------------------1,2,3
作者以往文章: