一,複習 二,今日內容: 三,如何定義函數: 四,函數的參數: 兩種實參: 1,位置實參: a,傳參兩種方式:實參名|實參具體值 b,必須按位置對形參進行傳值 2,關鍵字實參: a,傳參兩種方式:形參名=實參名 | 形參名=實參值 b,可以指名道姓對形參進行傳值,所以可以不用按位置進行傳參 ''' ...
一,複習
字元編碼
文件頭:py2—ASCII,py3—UTF-8
三種字元串:u' ' b ' ' r ' '
u' ' .endcode(' utf-8 ')
b' '.deconde(' utf-8 ')
str(b' ' , encode=' utf-8 ' )
bytes( u' ' , encode=' utf-8 ')
文件操作:
三步驟:
1,打開文件
2,操作文件(讀寫)
3,關閉
簡寫:
with open => 可以自動關閉文件流
操作模式:
主 :r w a x
從:t b +
seek:游標(偏移量,游標操作位置)與b模式結合
函數基礎:
函數的定義:def 函數名():函數體
函數調用:函數名()
函數的返回值:省略 空return return一個值 return多個值 =》本質返回一個裝有多個值得元組
二,今日內容:
1,函數的參數:實參與形參
2,函數對象:函數名
3,名稱空間與作用域:LEGB
4,閉包:函數的嵌套定義
5,裝飾器:閉包的一種應用場景
6,迭代器對象:迭代器,生成器,for迭代
7,匿名函數
8,內置函數
9,三元表達式,列表,字典生成式
10,模塊
三,如何定義函數:
1,功能的單一化
2,函數內部需要外部的資源:通過函數的參數來實現
3,函數執行後的結果需要告訴外界:通過返回值告訴給外界
四,函數的參數:
形參與實參:
形參:在函數定義時()里出現的參數
——形參本身沒有實際值(意義),在函數調用時,傳入什麼實參,形參就裝有什麼值
實參:在函數調用時()里出現的參數
——實參有實際值(意義)
重點:函數調用傳參:將實參的值賦值給形參 | 形參要獲取外界的值只能通過實參進行獲取
def fn(a,b): #a , b :形參
pass
a = 10
fn(a , 20) #a , 20 實參
兩種實參:
1,位置實參:
a,傳參兩種方式:實參名|實參具體值
b,必須按位置對形參進行傳值
2,關鍵字實參:
a,傳參兩種方式:形參名=實參名 | 形參名=實參值
b,可以指名道姓對形參進行傳值,所以可以不用按位置進行傳參
'''
def func(a,b,c):
print(a,b,c)
#func(10,b=20,200) 報錯:SyntaxError: positional argument follows keyword argument
'''
#重點:兩種實參在一起進行傳參時:必須位置在前,關鍵字在後
兩大形參分類:
形參種類:
1,位置形參:
——普通位置形參
——預設值形參
——可變長位置形參
2,關鍵字形參:
——有預設值關鍵字形參
——無預設值關鍵字形參
——可變長關鍵字
'''
def fn(a,b,*,x,y): #位置形參:a,b 關鍵字形參:x,y
pass
'''
重點:
1,*為分水嶺
2,位置實參只能給位置形參進行傳值
3,關鍵字實參可以給位置形參與關鍵字形參進行傳值
兩個帶預設值的形參:
'''
def fn2(a=10,*,x=20):
print(a,x)
fn2(100,x=200)
'''
總結:
1,有預設值的參數可以不用傳值
2,*前有預設值的叫預設值參數,屬於位置形參,可以被位置及關鍵字實參進行傳值
3,*後有預設值的叫有預設值的關鍵字形參,屬於關鍵字形參,只能被關鍵字實參進行傳值
4,如果省略*,有預設值的形參都是預設值參數
不帶預設值與帶預設值形參結合使用:
def fn3(a, b=10, *, x, y=20, z):
print(a, b, x, y, z)
fn3(100, x=200, z=300)
# 總結:
# 1.沒有預設值的必須傳參,有預設值的可以傳也可以不傳
# 2.位置有值的必須出現在無值之後,關鍵字順序不做要求
def fn4(a, b=10, *args, x, **kwargs):
print(a, b, x)
print(args)
print(kwargs)
fn4(10, 20, 30, x=100, y=200, z=300)
'''
總結:
1.可變長是用來接收未接收完的值(接收0到n個):
-- *args用來接收所有沒有接收完的位置(只能接收位置實參)
-- **kwargs用來接收所有沒有接收完的關鍵字(只能接收關鍵字實參)
2.*args必須出現在所以位置參數之後,**kwargs必須出現在所以參數之後
'''
# 常見應用場景
假設第一個位置永遠是參數name
def func4(*args, **kwargs):
name = args[0] # 將name抽出來
def func44(name, *args, **kwargs):
# name 可以直接接收,省了抽出來的過程
pass
'''
總結:
1.位置實參只能給位置形參傳值
2.關鍵字實參可以給位置及關鍵字形參傳值
3.有預設值的可以不用傳參
4.可變長位置形參只能接受位置實參,接受位置形參沒有接收完的位置實參,存放到元組中
5.可變長關鍵字形參只能接受關鍵字實參,接受關鍵字形參沒有接收完的關鍵字實參,存放到字典中
6.*args必須出現在所有位置形參之後,**kwargs必須在所有形參之後
def fn(*args, **kwargs):
print(args, kwargs)
fn([1, 2, 3], {'a':1 , 'b': 2}) # =>接收到的 ([1, 2, 3], {'a':1 , 'b': 2}) {}
fn(*[1, 2, 3], **{'a':1 , 'b': 2}) # =>接收到的 (1, 2, 3) {'a':1 , 'b': 2}
# 註:字元串也可以作為單列集合進行打散傳遞
fn(*'abc') # => ('a', 'b', 'c') {}
五,函數對象:
#函數名就是存放了函數的記憶體地址,存放了記憶體地址的變數都是對象,即 函數名 就是 函數對象
#函數對象的應用場景
1 可以直接被引用
2 可以當作函數參數傳遞
3 可以作為函數的返回值
4 可以作為容器類型的元素
'''
#功能體:
def add(n1,n2):
return n1 + n2
def low(n1,n2):
return n1 - n2
def jump(n1,n2):
return n1 * n2
#完成功能:
def computed(n1,n2,fn): #fn = add|low|jump
res = fn(n1,n2) #調用具體的功能
return res
#功能對應關係:
method_map = { #指令與函數對象的對應關係
'1':add,
'2':low,
'3':jump
}
#獲取功能:
def get_method(cmd):
if cmd in method_map:
return method_map[cmd] #返回 add|low|jump
return add #當指令錯誤,add作為預設功能
while True:
cmd = input('cmd')
res = get_method(cmd)(10,20) #根據指令獲取功能並調用得到結果
print(res)
'''
六:函數的嵌套調用
# 函數的嵌套調用:在一個函數內部調用另一個函數
# 求兩個數最大值
'''
def max_tow(n1,n2):
if n1 > n2:
return n1
return n2
#求三個數的最大值
def max_three(n1,n2,n3):
max = max_tow(n1,n2)
return max_tow(max,n3)
#求四個數的最大值
def max_four(n1,n2,n3,n4)
max = max_three(n1,n2,n3)
return max_tow(max,n4)
print(max_four(20,90,30,10))
'''
七:名稱空間:
# 名稱空間:存放名字與記憶體空間地址對應關係的容器
# 作用:解決由於名字有限,導致名字重覆發送衝突的問題 - 內置全局局部可以同時使用一個名字存放不同地址
# 三種名稱空間
# Built-in:內置名稱空間;系統級,一個;隨解釋器執行而產生,解釋器停止而銷毀
# Global:全局名稱空間;文件級,多個;隨所屬文件載入而產生,文件運行完畢而銷毀
# Local:局部名稱空間;函數級,多個;隨所屬函數執行而產生,函數執行完畢而銷毀
# 載入順序:Built-in > Global > Loca
# -- 採用堆棧存儲數據的方式(壓棧),導致內置最後被訪問
八,函數的嵌套定義:
# 函數的嵌套定義:在函數內部定義函數
# 誕生的理由:一個函數想使用另一個函數內部的變數,可以定義在其內部
'''
def func():
a = 10
def fn():
print(a)
return fn
new_fn = func()
new_fn()
'''
'''
#global :統一局部與全局的變數名
num = 10
def outer():
#global num
#num = 100
def inner():
global num
num = 1000
#nonlcal:統一局部與嵌套局部的變數名
def outer():
num = 100
def inner():
nonlcal num
num = 1000
'''
九,作用域:
# 作用域:名字起作用的範圍
# 作用:解決同名字可以共存問題 - 不同作用域相同名字的值都能在其作用域範圍下進行使用
'''
四種作用域: LEGB
Built-in:內置作用域 - 所有文件所有地方都可以被訪問
Global:全局作用域 - 在當前文件的所有位置
Enclosing:嵌套作用域 - 自身內部與內部的子函數
Local:局部作用域 - 只有自身內部
'''
# 載入順序:Built-in > Global > Enclosing > Local
# 訪問(查找)順序:報錯 < Built-in < Global < Enclosing < Local
# 作用範圍:Built-in > Global > Enclosing > Local
十,閉包
# 閉包:定義在函數內部的函數,這個內部的函數就是閉包
#應用場景:
1,可以去使用其他函數的內部變數,且還可以保證調用位置不變(閉包的函數對象作為那個函數的返回值)
'''
def outer():
count = 3000
def fn():
print(count) #能使用outer內部的變數count
return fn
#還是在外界調用
outer()() #outer()()=>fn()=>調用fn
'''
2,延遲執行(外層函數可以為內部函數傳遞參數)
'''
import requests
def outer(url):
def show_html():
response = requests.get(url)
print(response.text)
return show_html
#製作 爬百度與新浪的 函數對象
show_baidu = outer('https://www.baidu.com')
show_sina = outer('https://www.sina.com.cn')
#延遲的需求來了,需要爬百度,就用百度函數對象,需要爬新浪,就用新浪函數對象
show_baidu()
show_sina()
show_baidu()
'''
十一,裝飾器
# 裝飾器:裝飾器就是閉包的一個應用場景
# -- 外層函數與內層函數形成的閉包結構的一種綜合使用
# 重點:開放封閉原則
# 開放:拓展功能的點是開放的 - 可以為之前的函數添加新功能
# 封閉:1.不能改變原函數的源代碼 2.還有通過原函數的函數對象來調用函數
'''
def huaping():
print('插花功能')
temp = huaping
def my_huaping():
temp()
print('觀賞功能')
huaping = my_huaping
huaping()
'''
#------------------------------------------------------
'''
def huaping():
print('插花功能')
def outer(temp): #temp = huaping
def my_huaping():
temp()
print('觀賞功能')
return my_huaping
huaping = outer(huaping) #huaping = my_huaping
huaping()
'''
#------------------------------------------------------
'''
def outer(temp): #temp = huaping
def my_huaping():
temp()
print('觀賞功能')
return my_huaping
@outer #huaping = outer(huaping)
def huaping():
print('插花功能')
huaping()
'''
#-----------------------------------------------------
#被裝飾的函數可能有參有返回:裝飾器模板,可以滿足所有參數,且能裝飾原函數返回值
'''
def outer(func): #temp = huaping
def inner(*args , **kwargs):
pass
res = func(*args,**kwargs)
pass
return res
return inner
@outer
def any_method():
pass
'''
十二:裝飾器案例
#為登錄功能添加賬號檢驗功能:必須是3個及以上英文字母組成
'''
def check_user(func):
def inner(user,pwd):
if not(user.isalpha() and len(user) >= 3):
return '賬號不合法'
res = func(user,pwd)
return res
return inner
'''
#為登錄功能添加密碼檢驗功能:必須是3個及以上英文字母或數字組成
'''
def check_pwd(func):
def inner(*args,**kwargs):
pwd = args[1]
if not(pwd.isalnum() and len(pwd) >= 3):
return '密碼不合法'
res = func(*args,**kwargs)
return res
return inner
'''
#為登錄結果的修飾裝飾器:True => 登陸成功 ,False => 登錄失敗
'''
def change_res(func):
def inner(*args,**kwargs):
res = func(*args,**kwargs)
if res = True:
return '登陸成功'
return '登陸失敗'
return inner
'''
#裝飾器被執行的過程是從上至下
'''
@check_user #login = check_user(func=login)=inner
@check_pwd
@chang_res
def login(user,pwd): #被裝飾的函數對象
if user == 'Owen' and pwd == '123':
return True
return False
user = input('user: ')
pwd = input('pwd: ')
res = login(user,pwd)
print(res)
'''