1. 程式人生 > >閉包函式 (字元編碼,檔案處理,函式基礎總結)

閉包函式 (字元編碼,檔案處理,函式基礎總結)

字元編碼
產生亂碼的原因
1.存的時候和取的時候編碼方式不一致,只要找到對應的編碼資料就可以正常顯示
2.存的時候就已經亂了,儲存資料時,出現了當前編碼表無法識別的符號導致了亂碼

unicode和utf-8都支援萬國語言
unicode兩個位元組 固定長度 浪費時間 但是效率高 更適用於記憶體中
utf-8 可變長度 節省空間 效率相對低,更加適用於網路傳輸和IO操作

編碼與解碼
把記憶體中的unicode符號 編碼成指定的二進位制進行儲存 叫做編碼 encode
把硬碟上的二進位制 解碼成unicode 叫做解碼 decode
str.encode()得到bytes
bytes(二進位制).decode()得到str
在py3中字串變數都是unicode 所以不會亂碼
檔案處理
開啟檔案 open
讀 read
寫 write
關閉檔案 close
with 語法可以簡化書寫 自動close
r==rt
w==wt
a==at
t表示文字模式 會自動完成 編碼和解碼操作,讀和寫都是以字元為單位,只用於文字檔案
b表示位元組模式 沒有編碼和解碼過程,讀寫都是以位元組為單位,可用於任何檔案

函式基礎
為什麼
程式碼冗餘
結構不清晰,可讀性差
擴充套件性差,維護性差
什麼是函式
函式是一段實現某個功能的程式碼的集合體,相當於生活中的某個工具
需遵循 先定義 再呼叫
函式完整語法
def 函式名(引數列表):
文件註釋
函式體
return值
函式定義
有參
當函式體的程式碼邏輯需要依賴外界的資料才能完成功能時,例如upper()

無參
當函式體的程式碼邏輯不需要依賴外界的資料才能完成功能時,例如99乘法表

空函式
沒有函式體的函式稱之為空函式,用來在編寫程式初期定義程式的結構

函式呼叫
1.直接呼叫 函式名加括號
2.可以再表示式中呼叫函式
3.print(len('123'))可以將函式的返回值作為另一個函式的引數
函式引數
形參指的是在函式定義階段的引數
實參指的是 呼叫函式時傳遞的值

1.位置引數,有幾個就必須傳幾個,實參會按照順序依次賦值給形參
2.關鍵字引數,指的是實參,可以再呼叫時 按照形參的名字傳值.可以打破順序限制
3.預設值引數,可以在定義函式時,給形參指定一個值,需要注意 預設值應該設定為不可變型別
4.可變長形參
* 可變長的位置形參,可以接受溢位的位置實參,打包為一個元組型別
** 可變長關鍵字形參, 可以接受溢位的關鍵字實參,打包成一個字典型別
可變長實參
* 可以跟任何的可迭代型別(str,list,tuple,set,dict),會把後面的值打散成單個元素以位置實參傳給函式
** 可以跟mapping型別(dict),會把後面的字典打散成單個key-value以關鍵字實參傳給函式

當可變長形參後面還有別的引數時,如果他沒有預設值,則呼叫時
必須以關鍵字形式來傳值.這種引數就是命名關鍵字引數

函式返回值
return 返回一個值給函式呼叫者
可以是一個值,可以多個值,也可以是什麼都不寫就一個return會預設返回一個None
不進可用於返回一個值,還能用於結束一個函式的執行




閉包函式

函式巢狀
巢狀指的是,一個物體包含另一個物體
函式巢狀值的就是一個函式包含另一個函式
按照函式的兩個階段 分為
巢狀呼叫
指的是,在函式執行過程中呼叫了另一個函式
其好處是,可以簡化外層大函式的程式碼,使得結構更清晰
可以將一個大的賦值的功能拆分為多個簡單的小功能
def func1():
print('func1 run!')
def func2():
print('func2 run!')
func()

func2()

巢狀定義
指的是,在函式的函式體中定義了另一個函式
需要注意的是:內部定義的函式,只能在內部使用,外界無法直接訪問
唯一的使用場景就是閉包函式,除此之外不要這麼寫
def outer():
print('outer run!')
def inner():
print('inner run!')
inner()
outer()


名稱空間
namespace
儲存名詞與記憶體地址繫結關係的記憶體區域就是名稱空間
就是儲存名字的記憶體區域
名稱空間的分類
內建名稱空間,存的是直譯器自帶的名稱,例如print,len
生命週期:隨著直譯器的啟動而生效,隨著直譯器執行結束而失效
特點:其特點是在程式執行過程中一直有效

全域性名稱空間
只要是頂著最左邊寫的,沒有任何縮排的,就在全域性名稱空間中
生命週期:隨著py檔案的執行而生效,隨著py檔案的結束而失效
特點:其特點是在程式執行過程中一直有效
需要注意的是,在if中如果if是頂著最左邊的沒有縮排的那麼if裡面的名字也屬於全域性
同樣的,while,for,with都是如此

區域性名稱空間
存的是函式內定義的名字,
特點:僅在函式呼叫時臨時生效
生命週期:隨著函式的呼叫而生效,隨著函式的呼叫的結束而失效

名稱空間的載入順序
內建->全域性->區域性
名字的查詢順序
優先區域性 再全域性 再內建


作用域
域指的是區域,範圍,作用域指的就是作用區域,作用範圍有效範圍
簡單的說就是名字的有效範圍
儲存名詞的有三個地方
內建名稱空間
全域性名稱空間
區域性名稱空間
全域性作用域
由於,內建名稱空間的名字與全域性名稱空間的名字,可以再任何位置來訪問,
所以他們兩可以劃到同一範圍,稱之為全域性範圍即全域性作用域
區域性作用域
區域性名稱空間的名字只能在當前的函式中訪問,所以他單獨劃到一個範圍中
這個範圍稱之為區域性作用範圍即區域性作用域

global(全域性)與nonlocal(不使用本地) 關鍵字
global
當需要在函式內部修改全域性中的名字的值時需要使用global
注意,必須在使用這個名字之前宣告之前寫global
nonlocal(不使用本地) 宣告我要修改外層的a 而不是定義一個新的
當需要在內層函式中修改哇外層函式的名字時就需要使用nonlaca
會一層一層往外找,直到找到位置,但是隻能找到函式中的不能找到的全域性名字

函式物件
沒有新技術點
目的是為了讓你直到 函式都可以怎麼來使用,
函式是第一類物件
1.能夠被呼叫
2.可以當做容器型別的元素
3.可以當做函式的引數
4.可以當做函式的返回值
函式名除了可以呼叫之外與一個變數名沒有本質區別,變數能怎麼用,函式名就能怎麼用


閉包函式
閉包 一個函式將另一個函式關閉在內部,反過來說
一個函式被另一個函式包裹
閉包函式也是一種函式
其特點是:
1.該函式是定義在另一個函式中的
2.該函式包含了對外層函式中的名字的引用,無論在任何位置使用這個函式,其都包含了外部名字引用
滿足以上兩條 就稱為閉包函式
需要注意的是:名字所在的作用域 在函式定義階段就已經固定了,與呼叫位置無關

現階段 可以將閉包理解為 另一種為函式體傳值的方式
之前只能通過引數給函式傳值
現在可以通過閉包的方式

由於名稱空間與作用域的特點,內層定義的函式 只能在內層函式
而函式物件可以將一個函式作為返回值,是的內部函式也可以被外界使用