3.Python 进阶知识
生活随笔
收集整理的這篇文章主要介紹了
3.Python 进阶知识
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- Python 進階知識
- 知識點一 : 數據類型
- 1.數據類型 列表與元組
- 2.數據類型 字典與集合
- 3.數據類型 字符串
- 知識點二 : 推導式
- 1.列表推導式
- 2.字典推導式
- 3.元組推導式
- 4.集合推導式
- 知識點三 : 高階函數
- 1.filter 函數
- 2.map 函數
- 3.reduce 函數
- 4.zip 函數
- 5.enumerate 函數
- 知識點四 : 裝飾器
- 1.裝飾器 單個無參裝飾器修飾無參函數
- 2.裝飾器 單個無參裝飾器裝飾帶參函數
- 3.裝飾器 單個帶參裝飾器裝飾帶參函數
- 4.裝飾器 多個無參裝飾器修飾帶參函數
- 5.裝飾器 解決元信息丟失
- 6.裝飾器 基于類的裝飾器
- 7.裝飾器 內置裝飾器@property
- 8.裝飾器 內置裝飾器@staticmethod
- 9.裝飾器 內置裝飾器@classmethod
- 知識點五 : 閉包
- 1.閉包 閉包基本操作
- 2.閉包 閉包的作用域
- 3.閉包 閉包實際作用
- 4.閉包 判斷閉包函數
- 5.閉包 閉包存在的問題
- 知識點六 : 日期和時間
- 1.時間模塊 time
- 1.1 時間模塊 獲取時鐘基本信息
- 1.2 時間模塊 獲取時間戳
- 1.3 時間模塊 獲取可讀時間
- 1.4 時間模塊 從系統啟動時開始計時
- 1.5 時間模塊 處理器時鐘時間
- 1.6 時間模塊 性能計數器
- 1.7 時間模塊 時間組件
- 1.8 時間模塊 解析和格式化時間
- 2.日期模塊 datetime
- 2.1 日期模塊 date類
- 2.2 日期模塊 time類
- 2.3 日期模塊 datetime類
- 3.日歷模塊 calendar
- 知識點七 : 作用域
- 1.作用域 作用域解釋
- 2.作用域 Python中的作用域
- 3.作用域 global關鍵字
- 4.作用域 nonlocal關鍵字
Python 進階知識
知識點一 : 數據類型
1.數據類型 列表與元組
"""1.列表與元組最直接的的區別是:列表長度大小不固定,是可變的. --動態元組長度大小固定,不可變. --靜態2.__sizeof__()方法 : Python的內置函數,用來打印系統分配空間的大小.3.列表會一次性增加4個元素的空間,當空間使用完畢后才會繼續增加 (64位操作系統中地址占用8個字節)4.namedtuple模塊 : 繼承自tuple的子類,用來創建一個和tuple類似的對象,且對象擁有可訪問的屬性.5.初始化空列表使用 []比 list() 快6.非空列表與非空元組初始化時,元組的效率更高 """# 1.用列表檢測系統如何進行空間分配 my_list = [] print("初始化大小", my_list.__sizeof__(), ":", my_list)my_list.append("a") print("追加1個元素之后的大小", my_list.__sizeof__(), ":", my_list)my_list.append("b") print("追加2個元素之后的大小", my_list.__sizeof__(), ":", my_list)my_list.append("c") print("追加3個元素之后的大小", my_list.__sizeof__(), ":", my_list)my_list.append("d") print("追加4個元素之后的大小", my_list.__sizeof__(), ":", my_list)my_list.append("e") print("追加5個元素之后的大小", my_list.__sizeof__(), ":", my_list) print("--------------")# 2.使用namedtuple模塊 from collections import namedtuple Point = namedtuple(typename='Point', field_names=['x', 'y']) # typename相當于是創建的類名,field_names用于為創建的元組的每個元素命名,可以傳入列表或元組 p = Point(10, 20) print(p.x) print(p.y) print("--------------")# 3.比較 list() 與 [] 初始化效率 import timeit a = timeit.timeit('a=list()', number=10000000 ) b = timeit.timeit('a=[]', number=10000000 ) print(a) print(b) print("--------------")# 4.比較 非空元組 與 非空列表 初始化效率 import timeit a = timeit.timeit('a=("a","b","c")', number=10000) b = timeit.timeit('b=["a","b","c"]', number=10000) print(a) print(b) print("--------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 初始化大小 40 : [] 追加1個元素之后的大小 72 : ['a'] 追加2個元素之后的大小 72 : ['a', 'b'] 追加3個元素之后的大小 72 : ['a', 'b', 'c'] 追加4個元素之后的大小 72 : ['a', 'b', 'c', 'd'] 追加5個元素之后的大小 104 : ['a', 'b', 'c', 'd', 'e'] -------------- 10 20 -------------- 0.4988713 0.20966529999999994 -------------- 0.00011539999999998773 0.0003946999999999701 --------------進程已結束,退出代碼02.數據類型 字典與集合
"""1.字典:1.1 在使用字典索引鍵時,若鍵不存在則出現KeyError錯誤,解決方法是在索引鍵時使用get(key,default)函數即可.(如 my_dict.get("F","None"))2.集合:2.1 集合不支持索引操作,使用索引查找對應元素值會報錯(TypeError: 'set' object is not subscriptable)2.2 集合的執行效率遠高于列表 """# 1.字典與集合的效率問題 import time# 1.1 計算列表運行的時間 def find_unique_weight(students):# 聲明一個統計列表unique_list = []# 循環所有學生數據for id, weight in students:# 如果體重沒有在統計列表中if weight not in unique_list:# 新增體重數據unique_list.append(weight)# 計算列表長度ret = len(unique_list)return retid = [x for x in range(1, 10000)] weight = [x for x in range(1, 10000)] # 體重數據為了計算,也設置從 1 到 10000 students = list(zip(id, weight))start_time = time.perf_counter() find_unique_weight(students) end_time = time.perf_counter() print("列表運算時間為:{}".format(end_time - start_time))# 1.2 計算列表運行的時間def find_unique_weight(students):# 聲明一個統計集合unique_set = set()# 循環所有學生數據for id, weight in students:# 集合會自動過濾重復數據unique_set.add(weight)# 計算集合長度ret = len(unique_set)return retid = [x for x in range(1, 10000)] weight = [x for x in range(1, 10000)] students = list(zip(id, weight))start_time = time.perf_counter() find_unique_weight(students) end_time = time.perf_counter() print("集合運算時間為:{}".format(end_time - start_time))-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 列表運算時間為:0.6111517 集合運算時間為:0.0007663999999999449進程已結束,退出代碼03.數據類型 字符串
"""1.字符串:1.1 字符串是不可變的1.2 字符串拼接時,join函數 比 += 快 """# 1.比較同名字符串內存地址 my_str = "hello " print(id(my_str)) my_str += "world" print(id(my_str)) print(my_str) print("---------------")# 2.比較字符串拼接效率 import time# 2.1 += 寫法 def m0():s = ' 'for n in range(0, 100000):s += str(n)start_time = time.perf_counter() m0() end_time = time.perf_counter() print("代碼運行時間為:", end_time - start_time)# 2.2 join 寫法 def m1():l = []for n in range(0, 100000):l.append(str(n))s = ' '.join(l)start_time = time.perf_counter() m1() end_time = time.perf_counter() print("代碼運行時間為:", end_time - start_time)# 2.3 pythonic 寫法 def m2():s = ' '.join(map(str, range(0, 100000)))start_time = time.perf_counter() m2() end_time = time.perf_counter() print("代碼運行時間為:", end_time - start_time)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 2625249362416 2625250809136 hello world --------------- 代碼運行時間為: 0.027465000000000003 代碼運行時間為: 0.022872000000000003 代碼運行時間為: 0.0164642進程已結束,退出代碼0知識點二 : 推導式
1.列表推導式
"""1.列表推導式1.1 推導式格式:[表達式 for 迭代變量 in 可迭代對象 [if 條件表達式]]1.2 if 條件表達式非必選1.3 列表推導式運行效率高于傳統for循環寫法1.4 Python3中列表推導式具備局部作用域,表達式內部變量和賦值只在局部生效 """# 1.傳統for循環寫法 my_list = [1, 2, 3] new_list = [] for i in my_list:new_list.append(i * 2) print(new_list) print("--------------")# 2.列表推導式寫法 my_list = [1, 2, 3] new_list = [] nn_list = [i * 2 for i in my_list] print(nn_list) print("--------------")# 3.列表推導式if語句 nn_list = [i * 2 for i in my_list if i > 1] print(nn_list) print("--------------")# 4.列表推導式雙重for循環 nn_list = [(x, y) for x in range(3) for y in range(3)] print(nn_list) print("--------------")# 5.列表推導式局部性演示 x = 6 my_var = [x*2 for x in range(3)] print(my_var) print(x) print("--------------")# 6.列表推導式嵌套 my_var = [y*4 for y in [x*2 for x in range(3)]] print(my_var)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe [2, 4, 6] -------------- [2, 4, 6] -------------- [4, 6] -------------- [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] -------------- [0, 2, 4] 6 -------------- [0, 8, 16]進程已結束,退出代碼02.字典推導式
"""1.字典推導式1.1 推導式格式:{鍵:值 for 迭代變量 in 可迭代對象 [if 條件表達式]}1.2 字典中不能出現同名key,第二次出現的同名key將會覆蓋掉前一個同名key的值 """# 1.字典推導式演示 my_dict = {key: value for key in range(3) for value in range(2)} print(my_dict) print("--------------")# 2.字典推導式遍歷一個具有鍵值關系的可迭代對象 my_tuple_list = [('name', '王小明'), ('age', 18), ('class', 'no1'), ('like', 'python')] my_dict = {key: value for key, value in my_tuple_list} print(my_dict)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe {0: 1, 1: 1, 2: 1} -------------- {'name': '王小明', 'age': 18, 'class': 'no1', 'like': 'python'}進程已結束,退出代碼03.元組推導式
"""1.元組推導式:1.1 元組推導式運行結果返回的是一個地址值. """my_tuple = (i for i in range(10)) print(my_tuple)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe <generator object <genexpr> at 0x000001CFE12EFC10>進程已結束,退出代碼04.集合推導式
"""1.集合推導式:1.1 因為集合是無序且不重復的,所以會自動去掉重復元素導致每次運行顯示的順序不一樣. """my_set = {value for value in 'HelloWorld'} print(my_set)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe {'d', 'e', 'r', 'l', 'o', 'W', 'H'}進程已結束,退出代碼0知識點三 : 高階函數
1.filter 函數
"""1.filter 函數1.1 函數原型:filter ( function or None, iterable ) --> filter object- 第一個參數是判斷函數 ( 返回結果需要是 True 或 False).- 第二個為序列,該函數將對 iterable 序列依次執行 function ( item ) 操作, 返回結果是過濾后結果組成的序列.1.2 解釋:filter 函數對序列中元素進行篩選, 獲取符號條件的序列 """my_list = [1, 2, 3] my_new_list = filter(lambda x: x > 2, my_list) print(my_new_list) print(list(my_new_list)) # 使用list函數查看序列內容-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe <filter object at 0x000002DFEF283FA0> [3]進程已結束,退出代碼02.map 函數
"""1.map 函數1.1 map 函數原型:map(func, *iterables) --> map object1.2 解釋:map函數運行后生成一個list, 第一個參數是函數, 第二個參數是一個或多個序列1.3 map函數解決的問題:1.使用 map 函數不需要創建一個空列表.2.調用函數時不再需要帶括號,map 函數會自動調用目標函數.3.map 函數會自動匹配序列中的所有元素. """# 1.第一個參數為單參 my_list = [-1, 2, -3] my_new_list = map(abs, my_list) print(my_new_list) print(list(my_new_list)) # 使用list函數查看序列內容 print("-----------------")# 2.第一個參數為多參 def fun(x, y):return x + ymy_new_list = map(fun, [1, 2, 3], [4, 4, 4]) # fun 函數有2個參數,故需要兩個序列 print(my_new_list) print(list(my_new_list)) print("-----------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe <map object at 0x00000169BACF7FA0> [1, 2, 3] ----------------- <map object at 0x00000169BACF7EB0> [5, 6, 7] -----------------進程已結束,退出代碼03.reduce 函數
"""1.reduce函數1.1 函數原型:reduce(function, sequence[, initial]) -> value- 第一個參數是函數- 第二個參數是序列,返回結算結果之后的值1.2 解釋:reduce函數用于滾動計算應用于列表中的連續值 """# 1.測試代碼 from functools import reducemy_list = [1, 2, 3]def add(x, y):return x + ymy_new_list = reduce(add, my_list) print(my_list) # 1+2+3 print(my_new_list) print("-----------------")# 2.將測試代碼第三個參數設置為4 my_new_list = reduce(add, my_list, 4) # 第三個參數表示初始值,即累加操作初始的數值 print(my_list) # 4 + 1+2+3 print(my_new_list) print("-----------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe [1, 2, 3] 6 ----------------- [1, 2, 3] 10 -----------------進程已結束,退出代碼04.zip 函數
"""1.zip函數1.1 函數原型:zip(iter1 [,iter2 [...]]) --> zip object1.2 解釋:- zip函數將可迭代對象作為參數,將對象中對應的元素打包成一個個元組,然后返回由這些元組組成的列表.- 如果各個迭代器的元素個數不一樣,則返回列表長度與最短的對象相同,利用星號 (*)操作符將元組解壓為列表 """# 1.測試代碼 my_list1 = {1, 2, 3} my_list2 = ["a", "b", "c"] print(zip(my_list1, my_list2)) print(list(zip(my_list1, my_list2))) print("-----------------")# 2.測試代碼展示*操作符 my_list = [(1, 'a'), (2, 'b'), (3, 'c')] print(zip(*my_list)) print(list(zip(*my_list))) print("-----------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe <zip object at 0x00000177A7BB6540> [(1, 'a'), (2, 'b'), (3, 'c')] ----------------- <zip object at 0x00000177A7BB6580> [(1, 2, 3), ('a', 'b', 'c')] -----------------進程已結束,退出代碼05.enumerate 函數
"""1.enumerate函數:1.1 函數原型:enumerate(iterable, start=0)- sequence: 一個序列、迭代器或其他支出迭代對象;- start: 下標起始位置.1.2 解釋:enumerate函數用于將一個可遍歷的數據對象組合為一個索引序列,同時列出數據和數據下標,一般用在for循環當中. """weekdays = ['Mon', 'Tus', 'Wen', 'Thir'] print(enumerate(weekdays)) print(list(enumerate(weekdays)))-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe <enumerate object at 0x000001D7D6893CC0> [(0, 'Mon'), (1, 'Tus'), (2, 'Wen'), (3, 'Thir')]進程已結束,退出代碼0知識點四 : 裝飾器
1.裝飾器 單個無參裝飾器修飾無參函數
"""1.裝飾器 裝飾無參函數1.1 解釋:裝飾器簡單來理解就是套在函數上的函數,如想統計1000個具有不同功能的函數運行的時間時,需要重構的代碼量極為恐怖.而這時則只需要寫個統計時間的函數,再讓這1000個函數直接調用即可.簡單來說,裝飾器拓展了原函數的功能,又不需要修改原函數的代碼1.2 格式:@裝飾器名def 函數名():pass """# 自定義裝飾器并調用 import timedef go(func):# 這里的 wrapper 函數名可以為任意名稱def wrapper():s_time = time.perf_counter()func()e_time = time.perf_counter()print(f"函數{func.__name__}運行時間是:{e_time - s_time}") # func.__name__用來得到引用指向的真正名字return wrapper@go # go就是我們剛寫好的統計運行時間的函數,裝飾器使用@來調用 def func():i = 0while i < 1000:i += 1@go def func1():i = 0while i < 10000:i += 1if __name__ == '__main__':func() # 調用函數時,我們沒有對函數func做任何修改,但是函數func具有了更多的功能(計算運行時間的功能)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 函數func運行時間是:4.4900000000000495e-05進程已結束,退出代碼02.裝飾器 單個無參裝飾器裝飾帶參函數
import timedef go(func):def wrapper(x, y):s_time = time.perf_counter()func(x, y)e_time = time.perf_counter()print(f"函數{func.__name__}運行時間是:{e_time - s_time}")return wrapper@go def func(x, y):i = 0while i < 1000:i += 1print(f"x={x},y={y}")if __name__ == '__main__':func(33, 55)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe x=33,y=55 函數func運行時間是:6.230000000000124e-05進程已結束,退出代碼03.裝飾器 單個帶參裝飾器裝飾帶參函數
def log(text):def decorator(func):def wrapper(x):print('%s %s():' % (text, func.__name__))func(x)return wrapperreturn decorator# 1.使用帶參裝飾器,相當于是在裝飾器外又包裹了一個函數,使用該函數接受參數且返回一個裝飾器函數. # 2.運行順序為: my_fun = log('執行')(my_fun) # 3.注意: 裝飾器只能接收一個參數,且必須是函數類型. @log('執行') def my_fun(x):print(f"我是 my_fun 函數,我的參數 {x}")if __name__ == '__main__':my_fun(123)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 執行 my_fun(): 我是 my_fun 函數,我的參數 123進程已結束,退出代碼04.裝飾器 多個無參裝飾器修飾帶參函數
import timedef go(func):def wrapper(x, y):s_time = time.perf_counter()func(x, y)e_time = time.perf_counter()print(f"函數{func.__name__}運行時間是:{e_time - s_time}")return wrapperdef gogo(func):def wrapper(x, y):print("我是第二個裝飾器")return wrapper# 1.運行后 print(f"x={x},y={y}") 代碼運行結果丟失,這里涉及到多個修飾器執行順序問題 # 2.被裝飾的函數在最內層,裝飾器外函數與內函數間的語句沒有裝飾到目標函數函數上,而是在裝載裝飾函數時的附加操作.在對函數進行裝飾時,外函數和內函數間的代碼會被運行. # 3.在執行裝飾器代碼裝飾后,調用func(33,55)已經切換為go(gogo(func)). # 3.1 運行gogo(func)代碼,內容轉換如下: # def wrapper(x, y): # print("我是第二個裝飾器") # 3.2 運行go(wrapper)代碼,內容轉換如下: # s_time = time.perf_counter() # print("我是第二個裝飾器") # e_time = time.perf_counter() # print(f"函數{func.__name__}運行時間是:{e_time-s_time}") @go @gogo def func(x, y):i = 0while i < 1000:i += 1print(f"x={x},y={y}")if __name__ == '__main__':func(33, 55)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 我是第二個裝飾器 函數wrapper運行時間是:1.7799999999998373e-05進程已結束,退出代碼05.裝飾器 解決元信息丟失
# 1.使用裝飾器可大幅度提高代碼復用性,但是缺點是會導致原函數的原信息丟失,如函數的__doc__、__name__ # 2.導入functools.wraps來解決元信息丟失的問題 from functools import wraps# 裝飾器 def logged(func):@wraps(func)def logging(*args, **kwargs):print(func.__name__)print(func.__doc__)func(*args, **kwargs)return logging# 函數 @logged def f(x):"""函數文檔,說明"""return x * xprint(f.__name__) # 未導入前輸出logging, 導入后輸出 f print(f.__doc__) # 未導入前輸出None, 導入后輸出 函數文檔,說明-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe f 函數文檔,說明進程已結束,退出代碼06.裝飾器 基于類的裝飾器
class H1(object):# 1.__init__方法:接收一個函數作為參數,即待被裝飾的函數def __init__(self, func):self.func = func# 2.__call__方法:讓類對象可以調用,類似函數調用,觸發點是被裝飾的函數調用時觸發.def __call__(self, *args, **kwargs):return '<h1>' + self.func(*args, **kwargs) + '</h1>'@H1 def text(name):return f'text {name}'s = text('class') print(s)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe <h1>text class</h1>進程已結束,退出代碼07.裝飾器 內置裝飾器@property
"""1.Python property屬性1.1 解釋:property屬性可用來個屬性添加約束.如:溫度屬性,我們設置不得低于-273℃;成績屬性,我們不允許出現0分以下;使用property屬性將來修改約束條件時很方便,可在代碼的調用方式不變的情況下改變結果.1.2 使用方法:- @property 裝飾器- property() 函數"""class Student(object):def __init__(self, score=0):self._score = score@propertydef score(self):print(self._score)return self._score@score.setterdef score(self, value):print("setting score")if not isinstance(value, int):raise ValueError("score must be an integer!")if value < 0 or value > 100:raise ValueError('score must between 0 ~ 100!')self._score = value# 1.直接傳入成績 s = Student(60) s.score# 2.使用 @property 裝飾器傳入成績 s.score = 88 # 直接傳入參數即可,使用更加簡潔 s.score-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 60 setting score 88進程已結束,退出代碼08.裝飾器 內置裝飾器@staticmethod
class Foo:# 綁定方法def __init__(self, name):self.name = name# 靜態方法,不需要表示自身對象的self和自身類的cls參數,就跟使用函數一樣.@staticmethoddef show():print('have a good time!')# 實例化變量 test = Foo('LiHua') test.show() # 在不傳參情況下得到預期的結果:have a good time!-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe have a good time!進程已結束,退出代碼09.裝飾器 內置裝飾器@classmethod
class Foo:bar = 'Nice'# 綁定方法def __init__(self, name):self.name = name# 實例方法def print_name(self):print(self.name)# 靜態方法@staticmethoddef show():print('have a good time!')# 類方法:不需要self參數,但是第一個參數需要是表示自身類的cls參數.@classmethoddef get(cls):print(cls.bar)test = Foo('LiHua') # 實例化變量 test.print_name() test.show() test.get()-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe LiHua have a good time! Nice進程已結束,退出代碼0知識點五 : 閉包
1.閉包 閉包基本操作
"""1.閉包1.1 解釋:在 Python 中,閉包就是調用一個函數X,函數X返回一個Y函數,這個返回的函數Y就是閉包1.2 流程說明:1.在調用 func("外")時, 產生了一個閉包函數inner_func;2.該閉包函數內調用了外部函數func的參數parmas,此時parmas參數是自由變量;3.當func的聲明周期結束后,parmas這個變量依然存在,原因就是被閉包函數inner_func調用了而不會被回收.1.3 閉包的實現步驟:1.必須有一個內層函數;2.內層函數必須使用外層函數的變量,如果不使用則閉包將毫無意義;3.外層含的返回值必須是內層函數. """# 定義外部(外層)函數 def func(parmas):# 定義內部(內層)函數def inner_func(p):print(f"外部函數參數{parmas},內部函數參數{p}")# 一定要返回內層函數return inner_func# 調用外層函數,賦值給一個新變量 inner,此時的 inner 相當于內層函數,并且保留了自由變量 params inner = func("外") inner("內")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 外部函數參數外,內部函數參數內進程已結束,退出代碼02.閉包 閉包的作用域
def outer_func():my_list = []def inner_func(x):my_list.append(len(my_list) + 1)print(f"{x}-my_list:{my_list}")return inner_func# 1.自由變量my_list的作用域只跟 每次調用的外層函數 及 生成的變量有關; # 2.閉包每個實例引用的變量互不干擾. test1 = outer_func() test1("i1") test1("i1") test1("i1") test1("i1")test2 = outer_func() test2("i2") test2("i2") test2("i2") test2("i2")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe i1-my_list:[1] i1-my_list:[1, 2] i1-my_list:[1, 2, 3] i1-my_list:[1, 2, 3, 4] i2-my_list:[1] i2-my_list:[1, 2] i2-my_list:[1, 2, 3] i2-my_list:[1, 2, 3, 4]進程已結束,退出代碼03.閉包 閉包實際作用
def outer_func():msg = "王小明"def inner_func():print(msg)return inner_func# 1.閉包:保存了一些非全局變量,即保存局部信息不被銷毀. # 2.流程:使用閉包后,outer_func 函數在執行后, 原本不可再使用的 msg 變量變得可再使用; # 因為上面執行了outer_func之后,再調用outer的時候,msg變量也被輸出了.這種情況下 # 可以把局部變量當全局變量使用. outer = outer_func() outer()-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 王小明進程已結束,退出代碼04.閉包 判斷閉包函數
def outer_func():msg = "王小明"def inner_func():print(msg)return inner_funcouter = outer_func() outer() # 1.通過 函數名.__closure__判斷一個函數是否是閉包函數 # 2.返回元組中第一項是 CELL 即為閉包函數 print(outer.__closure__)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 王小明 (<cell at 0x00000186967F3FD0: str object at 0x00000186966A5570>,)進程已結束,退出代碼05.閉包 閉包存在的問題
def count():fs = []for i in range(1, 4):def f():return ifs.append(f)return fs# 1.閉包函數的問題是地址和值的問題,由操作系統抵觸原理導致. # 2.結論:避免在閉包中引用循環變量 或 后續會發生變化的變量. f1, f2, f3 = count() print(f1()) print(f2()) print(f3())-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 3 3 3進程已結束,退出代碼0知識點六 : 日期和時間
1.時間模塊 time
1.1 時間模塊 獲取時鐘基本信息
"""1.日期與時間:1.1 與操作日期與時間相關的三個模塊:1.time:可操作C語言庫中低端時間相關函數,時鐘時間和處理器運行時間都可以獲取.2.datetime:提供了日期與時間的高級接口3.calendar:提供通用日歷相關函數,用于創建數周、數月、數年的周期性事件.1.2 必要術語:1.紀元 ( epoch ): 時間開始的點,其值取決于平臺;- 對于Unix, 紀元的1970年1月1日00:00:00(UTC);- 要找出給定平臺的epoch,使用time.gmtime(0)進行查看.2.紀元秒數: 指紀元時間點以來經過的總秒數,通常不包含閏秒.- 程序員間常把 紀元秒數 稱為 時間戳. """import time# 1.get_clock_info 函數:用于獲取時鐘的基本信息 # 1.1 name可取的值: # - monotonic: time.monotonic() # - perf_counter: time.perf_counter() # - process_time: time.process_time() # - thread_time: time.thread_time() # - time: time.time() # 1.2 get_clock_info 函數的返回值具有的屬性: # - adjustable: 返回True或False.(如果時鐘可自動更改或由系統管理員手動更改則為True,否則為False) # - implementation: 用于獲取時鐘的基礎C函數的名稱(說白了就是調底層C的函數) # - monotonic: 如果時鐘不能倒退則為True,否則為False # - resolution: 以秒為單位的時鐘分辨率(float)available_clocks = [('monotonic', time.monotonic()),('perf_counter', time.perf_counter()),('process_time', time.process_time()),('time', time.time()), ]for clock_name, func in available_clocks:print('''{name}:adjustable : {info.adjustable}implementation: {info.implementation}monotonic : {info.monotonic}resolution : {info.resolution}current : {current}'''.format(name=clock_name,info=time.get_clock_info(clock_name),current=func))-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exemonotonic:adjustable : Falseimplementation: GetTickCount64()monotonic : Trueresolution : 0.015625current : 168333.437perf_counter:adjustable : Falseimplementation: QueryPerformanceCounter()monotonic : Trueresolution : 1e-07current : 0.0315589process_time:adjustable : Falseimplementation: GetProcessTimes()monotonic : Trueresolution : 1e-07current : 0.03125time:adjustable : Trueimplementation: GetSystemTimeAsFileTime()monotonic : Falseresolution : 0.015625current : 1658576633.6705935進程已結束,退出代碼01.2 時間模塊 獲取時間戳
import time# 1.time.time(): 獲取紀元秒數,將epoch開始之后的秒數以浮點數格式返回 print(time.time())-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 1658576718.0507917進程已結束,退出代碼01.3 時間模塊 獲取可讀時間
import time# 1.直接獲取可讀時間 print(time.ctime()) print("--------------")# 2.時間戳轉為可讀時間 localtime = time.localtime(time.time()) print("本地時間為 :", localtime) print("--------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe Sat Jul 23 19:46:07 2022 -------------- 本地時間為 : time.struct_time(tm_year=2022, tm_mon=7, tm_mday=23, tm_hour=19, tm_min=46, tm_sec=7, tm_wday=5, tm_yday=204, tm_isdst=0) --------------進程已結束,退出代碼01.4 時間模塊 從系統啟動時開始計時
import time# 1.monotonic time:從系統啟動時開始計時,從0開始單調遞增 time.monotonic() print("單調時間", time.monotonic())-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 單調時間 168508.031進程已結束,退出代碼01.5 時間模塊 處理器時鐘時間
"""1.time函數返回的是時間戳,clock函數返回的是處理器時鐘時間.該函數的返回值:- 在第一次調用時,返回的是程序運行的實際時間- 在第二次之后的調用,返回的是自第一次調用后到這次調用的時間間隔2.注意:Python3.8版本后已移除clock()函數;應使用time.perf_counter()或time.process_time()代替""" import timet0 = time.perf_counter() print(time.perf_counter() - t0, "程序運行時間")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 1.6000000000043757e-06 程序運行時間進程已結束,退出代碼01.6 時間模塊 性能計數器
"""1.性能計數器使用time.perf_counter函數進行操作- perf_counter函數的紀元是未定義的,一般使用該函數都是為了比較和計算,而非用作絕對時間- perf_counter函數用于測量較短持續時間的具有最高有效精度的時鐘,包括睡眠狀態消耗的時間,使用兩次調用才會生效2.與time.perf_counter函數功能相似的函數:- perf_counter_ns()- process_time()- process_time_ns() """ import timet0 = time.perf_counter() for i in range(100000):pass print("程序運行時間", time.perf_counter() - t0)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 程序運行時間 0.0032179000000000027進程已結束,退出代碼01.7 時間模塊 時間組件
import time# 1.time.gmtime(): 返回UTC中的當前時間 print(time.gmtime()) print("------------------")# 2.time.localtime(): 返回當前時區對應的時間 print(time.localtime()) print("------------------")# 3.time.localtime()): 接收struce_time類型數據并將其轉換成浮點型數值(即時間戳) # - tm_wday: 星期 # - tm_yday: 一年中的某一天 # - tm_isdst: 在夏令時生效時設置為1,夏令時不生效時設置為0,值-1表示未知 print(time.mktime(time.localtime())) print("------------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe time.struct_time(tm_year=2022, tm_mon=7, tm_mday=23, tm_hour=11, tm_min=49, tm_sec=40, tm_wday=5, tm_yday=204, tm_isdst=0) ------------------ time.struct_time(tm_year=2022, tm_mon=7, tm_mday=23, tm_hour=19, tm_min=49, tm_sec=40, tm_wday=5, tm_yday=204, tm_isdst=0) ------------------ 1658576980.0 ------------------進程已結束,退出代碼01.8 時間模塊 解析和格式化時間
| %a | 本地化的縮寫星期中沒人的名稱 |
| %A | 本地化的星期中沒人的完整名稱 |
| %b | 本地化的月縮寫名稱 |
| %B | 本地化的月完整名稱 |
| %c | 本地化的適當日期和時間表示 |
| %d | 十進制數 [01,31] 表示的月中日 |
| %H | 十進制數 [00,23] 表示的小時 (24小時制) |
| %I | 十進制數 [01,12] 表示的小時 (12小時制) |
| %j | 十進制數 [001,366] 表示的月中日 |
| %m | 十進制數 [01,12] 表示月 |
| %M | 十進制數 [00,59] 表示的分鐘 |
| %p | 本地化的 AM 或 PM |
| %S | 十進制數 [00,61] 表示的秒 |
| %U | 十進制 [00,53] 表示的一年中的周數 (星期日作為一周的第一天), 在第一個星期日之前的新年中的所有日子都被認為是在第 0 周. |
| %w | 十進制 [0(星期日), 6] 表示的周中日 |
| %W | 十進制 [00,53] 表示的一年中的周數 (星期一作為一周的第一天), 在第一個星期一之前的新年中的所有日子都被認為是在第 0 周. |
| %x | 本地化的適當日期表示 |
| %X | 本地化的適當時間表示 |
| %y | 十進制 [00,99] 表示的沒有世紀的年份 |
| %Y | 十進制 [00,99] 表示的帶世紀的年份 |
| %z | 時區偏移以格式 +HHMM 或 -HHMM 形式的UTC/GMT 的正或負時差指示, 其中H表示十進制小時數字, M表示小數分鐘數字 [-23:59, +23:59] |
| %Z | 時區名稱 (如果不存在時區, 則不包含字符) |
| %% | 字面的 '%' 字符 |
"""1.strftime()和strptime(): 使時間值在struct_time表示和字符串表示之間互相轉換. """ import time# 1.strftime()函數的使用: strftime和strptime函數區別只有中間的字符不同 x = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) print(x) print("----------------")# 2.strptime()函數的使用: 方向操作,字符串格式化成 time.struct_time struct_time = time.strptime(x, "%Y-%m-%d %H:%M:%S") print(struct_time) print("----------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 2022-07-23 19:50:32 ---------------- time.struct_time(tm_year=2022, tm_mon=7, tm_mday=23, tm_hour=19, tm_min=50, tm_sec=32, tm_wday=5, tm_yday=204, tm_isdst=-1) ----------------進程已結束,退出代碼0
2.日期模塊 datetime
2.1 日期模塊 date類
"""1.在 datetime 模塊中,python 提供了5個主要的對象類:1.1 datetime: 運行同時操作日期和時間;1.2 date: 只操作日期;1.3 time: 只操作時間;1.4 timedelta: 用于操作日期及其測量時間跨度;1.5 tzinfo: 處理時區;2.datetime 模塊下的 date類的屬性和方法:2.1 min、max: date對象能表示的最大、最小日期;2.2 resolution: date對象表示日期的最小單位,返回天;2.3 today(): 返回表示當前本地日期的date對象;2.4 fromtimestamp(timestamp): 根據時間戳,返回一個date對象.3.date對象的屬性和方法:3.1 d.year: 返回年;3.2 d.month: 返回月;3.3 d.day: 返回日;3.4 d.weekday(): 返回weekday,如果是星期一返回0,如果是星期二返回1,后面以此類推;3.5 d.isoweekday(): 返回weekday,如果是星期一返回1,如果是星期二返回2,后面以此類推;3.6 d.isocalendar(): 返回格式如(year, wk num, wk day);3.7 d.isoformat(): 返回格式如'YYYY-MM-DD'的字符串;3.8 d.strftime(fmt): 自定義格式化字符串, 與 time 模塊中的 strftime 類似. """ from datetime import date import time# 1.測試date類的屬性和方法 print('date.min:', date.min) print('date.max:', date.max) print('date.resolution:', date.resolution) print('date.today():', date.today()) print('date.fromtimestamp():', date.fromtimestamp(time.time())) print("----------------")# 2.測試date對象的屬性和方法 d = date(year=2022, month=7, day=23) print(d) print("----------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe date.min: 0001-01-01 date.max: 9999-12-31 date.resolution: 1 day, 0:00:00 date.today(): 2022-07-23 date.fromtimestamp(): 2022-07-23 ---------------- 2022-07-23 ----------------進程已結束,退出代碼02.2 日期模塊 time類
"""1.time類定義的類屬性:1.1 min、max: time類孫表示的最小和最大時間;- time.min = time(0, 0, 0, 0)- time.max = time(23, 59, 59, 999999)1.2 resolution: 時間的最小單位,這里是1微妙.2.time類提供的實例方法和屬性:2.1 t.hour | t.minute | t.second | t.microsecond: 時、分、秒、微妙;2.2 t.tzinfo: 時區信息;2.3 t.isoformat: 返回形如"HH:MM:SS"格式的字符串時間表示;2.4 t.strftime(fmt): 返回自定義格式化字符串.""" from datetime import time# 通過構造函數創建一個time對象 t = time(hour=20, minute=20, second=40) print(t)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 20:20:40進程已結束,退出代碼02.3 日期模塊 datetime類
"""1.datetime類是date類和time類的結合體 """ from datetime import datetime# 1.獲取當前日期和時間 dt = datetime.now() print(dt) print("----------------")# 2.獲取時間戳: 使用 datetime 的內置函數 timestamp() stamp = datetime.timestamp(dt) print(stamp) print("----------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 2022-07-23 20:45:50.143048 ---------------- 1658580350.143048 ----------------進程已結束,退出代碼0####2.4 日期模塊 timedelta類
"""1.通過 timedelta 函數返回一個timedelta時間間隔對象2.timedelta 函數沒有必要填參數,如果寫入一個整數就是間隔多少天的意思3.兩個時間間隔對象可以彼此之間相加或相減,返回的仍是一個時間間隔對象.4. 一個 datetime 對象如果減去一個時間間隔對象,那么返回的對應減去之后的 datetime 對象,然后兩個 datetime 對象如果相減,返回的是一個時間間隔對象. """ from datetime import timedelta# 1.間隔 10 天 print(timedelta(10)) print("----------------")# 2.跨度為1 周 print(timedelta(weeks=1)) print("----------------")-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 10 days, 0:00:00 ---------------- 7 days, 0:00:00 ----------------進程已結束,退出代碼03.日歷模塊 calendar
"""1.calendar模塊的函數都是日歷相關的,例如打印某月的字符月歷2.calendar模塊定義了 Calendar 類,它封裝了值的計算, 例如給定月份或年份中周的日期。通過 TextCalendar 和 HTMLCalendar 類可以生成預格式化的輸出. """ import calendarc = calendar.TextCalendar(calendar.SUNDAY) c.prmonth(2022, 7)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exeJuly 2022 Su Mo Tu We Th Fr Sa1 23 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31進程已結束,退出代碼0知識點七 : 作用域
1.作用域 作用域解釋
"""1.變量作用域: 指的是變量的有效作用范圍,- 大白話就是 Python 中的變量不是任意位置都可以訪問的,訪問有限制條件.2.一般情況下變量的作用域變化范圍是(從小到大): 塊級、函數、類、模塊、包- Python 中沒有塊級作用域. """# 1.演示Python無塊級作用域 # 因為沒有塊級作用域,故 if 代碼塊中的變量 x 可以被外部訪問到 if True:x = "hello world" print(x)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe hello world進程已結束,退出代碼02.作用域 Python中的作用域
"""1.Python的四種作用域:1.1 L (Local): 最內層, 包含局部變量, 例如函數(方法)內部;1.2 E (Enclosing): 包含非局部(nonlocal)也非全局(nonglobal)的變量, 在嵌套函數中, 函數 A 包含函數 B, 在 B 中去訪問 A 中的變量, 作用域就是 nonlocal;- 直白理解就是閉包函數外的函數中的變量1.3 G (Global): 代碼最外層, 全局變量;1.4 B (Built-in): 包含內建變量.2.在 Python 中變量尋找的順序是從內到外,先局部后外部, 再全局, 再內建, 這種規則叫做LEGB 規則. """# 1.演示Python中的作用域# 內建作用域 Built-in x = int(5 / 2)# 全局作用域 Global global_var = 0def outer():# 閉包函數外的函數中 Enclosingout_var = 1def inner():# 局部作用域 Localinner_var = 23.作用域 global關鍵字
"""1.定義在函數內部的變量擁有一個局部作用域,定義在函數外部的變量擁有全局作用域- 局部變量只能在其被聲明的函數內部訪問, 而全局變量則可以在整個程序范圍內訪問."""# 1.演示global關鍵字# 全局變量 x = 0def demo():# 此時的 x 是全局變量# 1.如果不使用全局關鍵字,則輸出結果函數內部是123,外部依然是0# 2.注意: global關鍵字要寫在變量操作前# 3.在函數內部使用一個變量,不修改值的前提下,沒有聲明,默認獲取的是全局變量的值.global xx = 123print("函數內是局部變量 x = ", x)demo() print("函數外是全局變量 x= ", x)-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 函數內是局部變量 x = 123 函數外是全局變量 x= 123進程已結束,退出代碼04.作用域 nonlocal關鍵字
"""1.如果要修改嵌套作用域(Enclosing 作用域)中的變量, 需要nonlocal關鍵字"""# 1.演示nonlocal關鍵字num = 10def outer():# 1.注意:nonlocal不能代替globalnum = 10 # 注釋掉本行報錯def inner():num = 1000def inner1():# nonlocal 關鍵字# 1.多重嵌套中,nonlocal只會上溯一層,如果上一層沒有,則會繼續上溯nonlocal numnum = 100print(num)inner1()print(num)inner()print(num)outer()# 查看局部變量具體有哪些 print(locals()) # 查看全局變量具體有哪些 print(globals())-------------------------------------------------- C:\Users\32495\Envs\python3.9.2\Scripts\python.exe 100 100 10 {'__name__': '__main__', '__doc__': '\n 1.如果要修改嵌套作用域(Enclosing 作用域)中的變量, 需要nonlocal關鍵字\n\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CE79543FD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\softwareCode\\00_Code\\Python代碼\\Python進階知識\\7.知識點七 作用域\\4.作用域 nonlocal關鍵字.py', '__cached__': None, 'num': 10, 'outer': <function outer at 0x000001CE7910F0D0>} {'__name__': '__main__', '__doc__': '\n 1.如果要修改嵌套作用域(Enclosing 作用域)中的變量, 需要nonlocal關鍵字\n\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CE79543FD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\softwareCode\\00_Code\\Python代碼\\Python進階知識\\7.知識點七 作用域\\4.作用域 nonlocal關鍵字.py', '__cached__': None, 'num': 10, 'outer': <function outer at 0x000001CE7910F0D0>}進程已結束,退出代碼0總結
以上是生活随笔為你收集整理的3.Python 进阶知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux背后的思想
- 下一篇: websocket python爬虫_p