虛擬機做的網(wǎng)站怎么讓外網(wǎng)訪問不了個人博客網(wǎng)站怎么做
Python函數(shù)學(xué)習(xí)
1.函數(shù)定義
在函數(shù)定義階段只檢查函數(shù)的語法問題
2.實參形參
????總結(jié):
(1)位置參數(shù)就是經(jīng)常用的按照位置順序給出實參的值;
(2)關(guān)鍵字實參形式:key=123;放在所有位置參數(shù)后;
(3)默認形參是直接在函數(shù)括號中指定某數(shù)的值,若傳實參時給出具體值則按照具體值來,若沒給則按默認值處理;
?**(4)**形參中的*
會將溢出的位置實參全部接收,然后存儲元組的形式,然后把元組賦值給后的參數(shù)。需要注意的是:*
后的參數(shù)名約定俗成為args。表示為:
def func(*args)
**(5)**形參中的**
會將溢出的關(guān)鍵字實參*全部接收,然后存儲字典的形式,然后把字典賦值給后的參數(shù)。需要注意的是:**
后的參數(shù)名約定俗成為kwargs。表示為:def func(**kwargs)
3.函數(shù)是對象,可以被當(dāng)做數(shù)據(jù)進行處理
4.global和nonlocal關(guān)鍵字
第一,兩者的功能不同。global關(guān)鍵字修飾變量后標(biāo)識該變量是全局變量,對該變量進行修改就是修改全局變量,而nonlocal關(guān)鍵字修飾變量后標(biāo)識該變量是上一級函數(shù)中的局部變量,如果上一級函數(shù)中不存在該局部變量,nonlocal位置會發(fā)生錯誤(最上層的函數(shù)使用nonlocal修飾變量必定會報錯)。
第二,兩者使用的范圍不同。global關(guān)鍵字可以用在任何地方,包括最上層函數(shù)中和嵌套函數(shù)中,即使之前未定義該變量,global修飾后也可以直接使用,而nonlocal關(guān)鍵字只能用于嵌套函數(shù)中,并且外層函數(shù)中定義了相應(yīng)的局部變量,否則會發(fā)生錯誤(見第一)
【注:這兩段引用知乎作者的內(nèi)容,侵權(quán)刪】
global x
nonlocal x
(1)在局部想要修改全局的可變類型,不需要任何聲明,可以直接修改。
(2)在局部如果想要修改全局的不可變類型,需要借助global聲明,聲明為全局的變量,即可直接修改。
函數(shù)進階
1.閉包函數(shù)和裝飾器
裝飾器就是閉包的一種應(yīng)用,下面的代碼是裝飾器模板:
def deco(func):def wrapper(*args,**kwargs):res = func(*args,**kwargs)return resreturn wrapper
裝飾器在大段程序中的使用方法(裝飾器語法糖——即讓裝飾器用起來更方便簡潔的東西):直接在要使用裝飾器的函數(shù)上方@裝飾器,例:
def deco(func):def wrapper(*args, **kwargs):res = func(*args, **kwargs)return resreturn wrapper@deco # home =deco(home)
def home(name, pwd, tag=1):print(f"welcome {name} to home page")return name
應(yīng)用場景:
如果我們已經(jīng)上線了一個項目,我們需要修改某一個方法,但是我們不想修改方法的使用方法,這個時候可以使用裝飾器。因為軟件的維護應(yīng)該遵循開放封閉原則,即軟件一旦上線運行后,軟件的維護對修改源代碼是封閉的,對擴展功能指的是開放的
應(yīng)用實例:
import timecurrent_user = {'username': None}def login(func):# func = 最原始的indexdef wrapper(*args, **kwargs):if current_user['username']:res = func(*args, **kwargs)return resuser = input('username: ').strip()pwd = input('password: ').strip()engine = 'file'if engine == 'file':print('base of file')if user == 'nick' and pwd == '123':print('login successful')current_uesr['usre'] = userres = func(*args, **kwargs)return reselse:print('user or password error')elif engine == 'mysql':print('base of mysql')elif engine == 'mongodb':print('base of mongodb')else:print('default')return wrapper@login #home=login(home)這樣做的好處的可以減少登錄的次數(shù),只需每次判斷是否已登錄,而不需要重復(fù)寫登錄的代碼。即給home()和index()都增加了登錄的功能
def home(name):print(f"welcome {name} to home page")time.sleep(1)@login #index=login(index)
def index():print('welcome to index')time.sleep(1)res = index()
2.迭代器和生成器
(1)實際上生成器是迭代器的一種,只是生成器是自己寫的迭代器;
迭代器
幾個概念:
**可迭代的對象:**Python內(nèi)置str、list、tuple、dict、set、file都是可迭代對象
(Python中內(nèi)置有__iter__方法的都叫可迭代的對象)
(2)迭代器定義:
一個類如果實現(xiàn)了「迭代器協(xié)議」,就可以稱之為「迭代器」。
什么是「迭代器協(xié)議」呢?
在 Python 中,實現(xiàn)迭代器協(xié)議就是實現(xiàn)以下 2 個方法:
__iter__:這個方法返回對象本身,即 self
__next__:這個方法每次返回迭代的值,在沒有可迭代元素時,拋出 StopIteration 異常
#迭代器應(yīng)用實例
s = 'hello'
iter_s = s.__iter__()while True:try:print(iter_s.__next__())except StopIteration:break
#輸出結(jié)果為:
#h
#e
#l
#l
#o
(3)for循環(huán)又稱作迭代器循環(huán),in的后面必須是可迭代對象
lis = [1, 2, 3]
for i in lis:print(i)
生成器
(1)yield關(guān)鍵字:函數(shù)中但凡出現(xiàn)yield關(guān)鍵字,再調(diào)用函數(shù),就不會繼續(xù)執(zhí)行函數(shù)體代碼,而是會返回一個值
(2)yield和return的區(qū)別:
yield 接收一個值并繼續(xù)執(zhí)行后續(xù)代碼(未指定默認接收None),而return直接接收一個值并直接結(jié)束函數(shù),不再執(zhí)行其后的代碼;
def func():print('from func 1')yield 'a'print('from func 2')yield 'b'g = func()
print(F"g.__iter__ == g: {g.__iter__() == g}") #迭代器執(zhí)行_iter_的結(jié)果是它本身,這也證明了生成器就是迭代器res1 = g.__next__() #from func 1
print(f"res1: {res1}") #ares2 = next(g) #from func 2
print(f"res2: {res2}") #bfor i in g:print(i)
#for循環(huán)的結(jié)果:(a,b沒有拿變量來接收,打印不出來)
#from func 1
#a
#from func 2
#b
再來看一個直觀的生成器例子:
def i_wanna_return():yield 'a'yield 'b'yield 'c'for i in i_wanna_return():print(i)
#結(jié)果:
#a
#b
#c