python带参数装饰器 函数名_python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)...
一、函數(shù)名應(yīng)用
函數(shù)名是什么?函數(shù)名是函數(shù)的名字,本質(zhì):變量,特殊的變量。
函數(shù)名(),執(zhí)行此函數(shù)。
python 規(guī)范寫(xiě)法
1. #后面加一個(gè)空格,再寫(xiě)內(nèi)容,就沒(méi)有波浪線了。
2.一行代碼寫(xiě)完,下面一行的的內(nèi)容要空2行,
3.逗號(hào)2個(gè)邊的內(nèi)容要有空格。
如果是不規(guī)范的寫(xiě)法,Pycharm編輯器,會(huì)有灰色的波浪線顯示。
1.單獨(dú)打印函數(shù)名
def func1():
print(666)
print(func1)
執(zhí)行輸出:
打印的是一個(gè)函數(shù)內(nèi)存地址
2.函數(shù)名的賦值
def func2():
print(666)
f = func2
print(f())
執(zhí)行輸出:
666
None
3.函數(shù)名可以作為容器類(lèi)數(shù)據(jù)的元素
下面的函數(shù)都要執(zhí)行
def f1():
print(111)
def f2():
print(222)
def f3():
print(333)
def f4():
print(444)
寫(xiě)4個(gè)執(zhí)行代碼就可以了
f1()
f2()
f3()
f4()
如果是100個(gè)呢?
使用for循環(huán)批量執(zhí)行函數(shù)
def f1():
print(111)
def f2():
print(222)
def f3():
print(333)
def f4():
print(444)
l1 = []
for i in range(1, 5):
l1.append('f' + str(i))
for i in l1:
eval(i)()
執(zhí)行輸出:
111
222
333
444
4.函數(shù)名可以作為參數(shù)
def f1():
print(666)
def f2(x):
x()
f2(f1)
執(zhí)行輸出:
666
分析如下:
def f1():
print(666)
def f2(x): # x = f1
x() # f1()
f2(f1) #將f1函數(shù)作為變量傳參給f2,x()表示執(zhí)行函數(shù)f1(),輸出666
5.函數(shù)名可以作為函數(shù)的返回值。
def f11(x):
return x #將返回值傳給調(diào)用者f11(5),此時(shí)ret = 5
ret = f11(5)
print(ret)
執(zhí)行輸出:
5
def f1():
print(666)
def f2(x):
return x
f2(f1)()
執(zhí)行輸出:
666
代碼分析:
def f1():
print(666)
def f2(x): # x = f1
return x #將f1返回給函數(shù)調(diào)用者f2(f1),此時(shí)就相當(dāng)于 f1 = f2(f1)
f2(f1)() #將f1函數(shù)作為變量傳參給f2,return之后f2(f1)等于f1,f1()就表示執(zhí)行f1函數(shù),輸出666
f1是一個(gè)特殊變量,加()就可以執(zhí)行了
第一類(lèi)對(duì)象( first-class object)指
1.可在運(yùn)行期創(chuàng)建
2.可用作函數(shù)參數(shù)或返回值
3.可存入變量的實(shí)體
*不明白?那就記住一句話,就當(dāng)普通變量用
函數(shù)名就是第一類(lèi)對(duì)象
加括號(hào),就可以執(zhí)行了。
二、閉包
閉包函數(shù):
內(nèi)部函數(shù)包含對(duì)外部作用域而非全劇作用域變量的引用,該內(nèi)部函數(shù)稱(chēng)為閉包函數(shù)
有如下代碼,請(qǐng)補(bǔ)全代碼,在函數(shù)外部執(zhí)行inner()函數(shù)
def wrapper():
def inner():
print(666)
第一種寫(xiě)法
def wrapper():
def inner():
print(666)
inner()
wrapper()
執(zhí)行輸出:
666
第二種寫(xiě)法
def wrapper():
def inner():
print(666)
return inner #將inner函數(shù)返回給調(diào)用者ret,此時(shí)ret = inner
ret = wrapper()
ret() #執(zhí)行inner函數(shù)
執(zhí)行輸出:
666
ret = wrapper()
ret()
等同于
wrapper()()
return inner之后,inner由臨時(shí)空間,轉(zhuǎn)換為全局空間了。
因?yàn)閞et賦值了
閉包舉例
def wrapper():
name = '老男孩'
def inner():
print(name)
inner()
wrapper()
執(zhí)行輸出:
老男孩
如何判斷它是否是一個(gè)閉包函數(shù)呢??內(nèi)層函數(shù)名.__closure__? cell 就是=閉包
def wrapper():
name = '老男孩'
def inner():
print(name)
inner()
print(inner.__closure__)
wrapper()
執(zhí)行輸出:
老男孩
(,)
出現(xiàn)了cell,就表示它是一個(gè)閉包函數(shù)
name = '老男還'
def wrapper():
def inner():
print(name)
inner()
print(inner.__closure__)
wrapper()
執(zhí)行輸出:
老男還
None
返回值為None 表示它不是閉包
因?yàn)閚ame是一個(gè)全局變量
如果函數(shù)調(diào)用了外層變量而非全局變量,那么它就是閉包
name = '老男還'
def wrapper2():
name1 = 'alex'
def inner():
print(name)
print(name1)
inner()
print(inner.__closure__)
wrapper2()
執(zhí)行輸出:
老男還
alex
(,)
只要引用了外層變量至少一次,非全局的,它就是閉包
面試題:
下面的函數(shù),是一個(gè)閉包嗎?
name = '老男孩'
def wraaper2(n):
# n = '老男孩' 相當(dāng)于
def inner():
print(n)
inner()
print(inner.__closure__) # None
wraaper2(name)
它也是一個(gè)閉包
雖然wraaper2傳了一個(gè)全局變量,但是在函數(shù)wraaper2內(nèi)部,inner引用了外層變量,相當(dāng)于在函數(shù)inner外層定義了n = '老男孩',所以inner是一個(gè)閉包函數(shù)
閉包的好處
當(dāng)函數(shù)開(kāi)始執(zhí)行時(shí),如果遇到了閉包,他有一個(gè)機(jī)制,他會(huì)永遠(yuǎn)開(kāi)辟一個(gè)內(nèi)存空間,將必包中的變量等值放入其中,不會(huì)隨著函數(shù)的執(zhí)行完畢而消失。
舉一個(gè)例子
from urllib.request import urlopen
content = urlopen('http://www.xiaohua100.cn/index.html').read().decode('utf-8')
print(content)
執(zhí)行輸出,是一堆網(wǎng)頁(yè)源代碼。
爬3次
from urllib.request import urlopen
content1 = urlopen('http://www.xiaohua100.cn/index.html').read().decode('utf-8')
content2 = urlopen('http://www.xiaohua100.cn/index.html').read().decode('utf-8')
content3 = urlopen('http://www.xiaohua100.cn/index.html').read().decode('utf-8')
內(nèi)存開(kāi)了3次,很占用內(nèi)存
把它封裝成閉包
from urllib.request import urlopen
def index():
url = "http://www.xiaohua100.cn/index.html"
def get():
return urlopen(url).read()
return get
xiaohua = index()
content = xiaohua()
print(content)
這個(gè)例子,只有第一遍,是從網(wǎng)站抓取的。
之后的執(zhí)行,直接從內(nèi)存中加載,節(jié)省內(nèi)存空間
三、裝飾器初識(shí)
裝飾器本質(zhì)上就是一個(gè)python函數(shù),他可以讓其他函數(shù)在不需要做任何代碼變動(dòng)的前提下,增加額外的功能,裝飾器的返回值也是一個(gè)函數(shù)對(duì)象。
裝飾器的應(yīng)用場(chǎng)景:比如插入日志,性能測(cè)試,事務(wù)處理,緩存等等場(chǎng)景。
現(xiàn)在我有一個(gè)需求,我想讓你測(cè)試這個(gè)函數(shù)的執(zhí)行時(shí)間,在不改變這個(gè)函數(shù)代碼的情況下:
先寫(xiě)一個(gè)雛形
import time
def func1():
print('in func1')
time.sleep(1) # 模擬程序邏輯
start = time.time()
func1()
print(time.time() - start)
執(zhí)行輸出:
in func1
1.0001070499420166
封裝成函數(shù)
傳一個(gè)參數(shù),函數(shù)名,就可以查看函數(shù)的執(zhí)行時(shí)間了
import time
def func1():
print('in func1')
time.sleep(1) # 模擬程序邏輯
def timmer(f):
start_time = time.time()
f()
end_time = time.time()
print('此函數(shù)的執(zhí)行時(shí)間為{}'.format(end_time - start_time))
timmer(func1)
執(zhí)行輸出:
in func1
此函數(shù)的執(zhí)行時(shí)間為1.0002098083496094
原來(lái)100個(gè)函數(shù),都是調(diào)用了func1(),現(xiàn)在測(cè)試函數(shù),需要timeer(func1)。如果想測(cè)試所有調(diào)用地方的執(zhí)行時(shí)間,那么需要修改100個(gè)函數(shù)位置,改成timeer(func1),太麻煩了。
不能更改原來(lái)的調(diào)用方式,同時(shí)需要加一個(gè)函數(shù)執(zhí)行時(shí)間的功能。怎么辦呢?
要無(wú)限接近于原來(lái)的調(diào)用方法,慢慢來(lái)
先來(lái)講一個(gè)變量賦值的例子
a = 1
b = a
a = 2 #a重新賦值了,原來(lái)a的值不存在了。但是b還是等于原來(lái)a的值,也就是1
print(a,b)
執(zhí)行輸出2,1
1.更改執(zhí)行方式
import time
def func1():
print('in func1')
time.sleep(1) # 模擬程序邏輯
def timmer(f):
start_time = time.time()
f()
end_time = time.time()
print('此函數(shù)的執(zhí)行時(shí)間為{}'.format(end_time - start_time))
f1 = func1 #定義f1等于func1函數(shù)
func1 = timmer #定義func1等于timmer,等式計(jì)算右邊的。此時(shí)func1被覆蓋了,和原來(lái)的沒(méi)有任何關(guān)系,f1還是等于原來(lái)的func1
func1(f1) #此時(shí)相當(dāng)于執(zhí)行 timmer(老的func1)
執(zhí)行輸出:
in func1
此函數(shù)的執(zhí)行時(shí)間為1.0001263618469238
在精簡(jiǎn)一步
import time
def func1():
print('in func1')
time.sleep(1) # 模擬程序邏輯
def timmer(f): # f = func1
def inner():
start_time = time.time()
f() #執(zhí)行func1()
end_time = time.time()
print('此函數(shù)的執(zhí)行時(shí)間為{}'.format(end_time - start_time))
return inner #將inner函數(shù)返回給函數(shù)調(diào)用者timmer(func1)
a = timmer(func1) #等式計(jì)算右邊的,將func1函數(shù)傳給timmer函數(shù)
a() #此時(shí)相當(dāng)于執(zhí)行了inner函數(shù)
執(zhí)行輸出:
in func1
此函數(shù)的執(zhí)行時(shí)間為1.000577449798584
最終版本
import time
def timmer(f): # 2接收參數(shù).f = func1
def inner():
start_time = time.time() #5.進(jìn)入inner函數(shù)
f() #6.執(zhí)行f(),也就是原來(lái)的func1函數(shù)。雖然func1被覆蓋了,但是之前的值還存在。請(qǐng)參考上面a,b賦值的例子
end_time = time.time() #10 獲取當(dāng)前時(shí)間
print('此函數(shù)的執(zhí)行時(shí)間為{}'.format(end_time - start_time)) #11.輸出差值
return inner #3.將inner函數(shù)返回給函數(shù)調(diào)用者timmer(func1),此時(shí)程序結(jié)束,繼續(xù)執(zhí)行func1()
def func1(): #7.進(jìn)入函數(shù)
print('in func1') # 8.打印輸出
time.sleep(1) # 9.等待1秒
func1 = timmer(func1) #1.等式計(jì)算右邊的,將func1函數(shù)傳給timmer函數(shù),此時(shí)func1被覆蓋了,原來(lái)func1的不存在了。
func1() #4.這里的func1是全新的func1,就是上面的賦值,此時(shí)相當(dāng)于執(zhí)行 inner函數(shù)
代碼從上至下執(zhí)行,先加載函數(shù)變量timmer和func1。在執(zhí)行上文說(shuō)的第1步以及后面的,請(qǐng)看數(shù)字。
執(zhí)行輸出:
in func1
此函數(shù)的執(zhí)行時(shí)間為1.0009608268737793
但是加這一步,還是不太方便。那么python給這種情況,加了一個(gè)語(yǔ)法糖@
語(yǔ)法糖指那些沒(méi)有給計(jì)算機(jī)語(yǔ)言添加新功能,而只是對(duì)人類(lèi)來(lái)說(shuō)更"甜蜜"的語(yǔ)法
import time
def timmer(f): # f = func1
def inner():
start_time = time.time()
f() #執(zhí)行func1()
end_time = time.time()
print('此函數(shù)的執(zhí)行時(shí)間為{}'.format(end_time - start_time))
return inner #將inner函數(shù)返回給函數(shù)調(diào)用者timmer(func1)
#語(yǔ)法糖@
@timmer #相當(dāng)于 func1 = timmer(func1) #這一步就已經(jīng)覆蓋了
def func1():
print('in func1')
time.sleep(1) # 模擬程序邏輯
func1() #相當(dāng)于執(zhí)行了inner()函數(shù)
想測(cè)試誰(shuí),前面加@裝飾器函數(shù),即可。
裝飾器利用return制造了一個(gè)假象,func1()執(zhí)行,其實(shí)是執(zhí)行了inner()
func1()已經(jīng)把原來(lái)的func1()給覆蓋了
這個(gè)裝飾器,還不夠完整,函數(shù)不能傳參數(shù)
先來(lái)舉個(gè)例子
def func2(a1,b1): #4.執(zhí)行函數(shù),接收位置參數(shù)a1=1,b1=2
print(a1,b1) #5. 輸出1,2
def func3(a,b): #2. 接收參數(shù),a=1,b=2
func2(a,b) #3. 執(zhí)行函數(shù)func2(1,2)
func3(1,2) #1.傳位置參數(shù)1,2
執(zhí)行輸出:
1 2
func3執(zhí)行一遍后,將a,b的值,傳給a1,b1了
上面裝飾器的例子,func1,要傳2個(gè)參數(shù)a,b
import time
def timmer(f):
def inner(a,b):
start_time = time.time()
f(a,b)
end_time = time.time()
print('此函數(shù)的執(zhí)行時(shí)間為{}'.format(end_time - start_time))
return inner
@timmer
def func1(a,b):
print('in func1 {}{}'.format(a,b))
time.sleep(1) # 模擬程序邏輯
func1(1,2)
執(zhí)行輸出:
in func1 12
此函數(shù)的執(zhí)行時(shí)間為1.0006024837493896
如果有多個(gè)參數(shù)呢?改成動(dòng)態(tài)參數(shù)
import time
def timmer(f):
def inner(*args,**kwargs):
start_time = time.time()
f(*args,**kwargs)
end_time = time.time()
print('此函數(shù)的執(zhí)行時(shí)間為{}'.format(end_time - start_time))
return inner
@timmer
def func1(*args,**kwargs):
print('in func1 {}{}'.format(args,kwargs))
time.sleep(1) # 模擬程序邏輯
func1(1,2,a='3',b=4)
執(zhí)行輸出:
in func1 (1, 2){'b': 4, 'a': '3'}
此函數(shù)的執(zhí)行時(shí)間為1.000101089477539
面試題,手寫(xiě)一個(gè)裝飾器
寫(xiě)裝飾器,約定俗成,函數(shù)名為wrapper
第一步
def wrapper(func):
def inner():
func()
return inner
第二步
def wrapper(func):
def inner(*args,**kwargs):
func(*args,**kwargs)
return inner
第三步
def wrapper(func):
def inner(*args,**kwargs):
'''被裝飾函數(shù)之前'''
ret = func(*args,**kwargs)
'''被裝飾函數(shù)之后'''
return ret
return inner
完整的
def wrapper(func):
def inner(*args,**kwargs):
'''被裝飾函數(shù)之前'''
ret = func(*args,**kwargs)
'''被裝飾函數(shù)之后'''
return ret
return inner
@wrapper
def func(*args,**kwargs):
print(args,kwargs)
return 666
print(func())
作業(yè):
使用函數(shù)完成用戶登錄和注冊(cè)功能
#先讓用戶選擇,是登陸還是注冊(cè)
#選擇序號(hào)完畢之后,運(yùn)行相應(yīng)的程序,
#驗(yàn)證成功之后,可以讓其繼續(xù)選擇,登陸還是注冊(cè),還可以選擇退出。
1.先準(zhǔn)備函數(shù)的雛形
def registered_username(username):
'''
#判斷注冊(cè)用戶名是否存在
:param username: 用戶名
:return: True 存在 False 不存在
'''
def write_file(username,password):
'''
#寫(xiě)入用戶列表文件
:param username: 用戶名
:param password: 密碼
:return: True 寫(xiě)入成功 False 寫(xiě)入失敗
'''
def username_password(username,password):
'''
#判斷用戶名和密碼是否匹配
:param username: 用戶名
:param password: 密碼
:return: True 匹配成功 False 匹配失敗
'''
def register(*args,**kwargs):
'''
注冊(cè)邏輯
:return:
'''
pass
def login(*args,**kwargs):
'''
登錄邏輯
:return:
'''
pass
def user_menu(*args,**kwargs):
'''
# 用戶菜單
'''
pass
2.先寫(xiě)菜單
def user_menu(*args,**kwargs):
'''
# 用戶菜單
'''
# 判斷文件是否存在,不存在創(chuàng)建文件
file_exists()
# 循環(huán)
while True:
# 打印菜單
menu = ['注冊(cè)', '登錄', '退出']
print('bbs系統(tǒng)'.center(25, '#'))
for i in range(len(menu)):
print('{}\t{}'.format(i + 1, menu[i]))
print(''.center(27, '#'))
number = input('請(qǐng)選擇序號(hào): ').strip()
if number == '1':
# 執(zhí)行注冊(cè)程序
register()
elif number == '2':
# 執(zhí)行登錄程序
login()
elif number == '3':
exit()
else:
print('輸入錯(cuò)誤,請(qǐng)重新輸入!')
3.寫(xiě)判斷用戶列表文件是否存在
def file_exists(*args,**kwargs):
'''
# 判斷用戶列表文件是否存在
:return: True 存在 False 不存在
'''
# 判斷文件是否存在
if os.path.exists(file_name):
return True
else:
with open(file_name, encoding='utf-8', mode='w') as mk:
mk.write('張三 123')
return False
4.再寫(xiě)注冊(cè)邏輯
def register(*args,**kwargs):
'''
注冊(cè)邏輯
:return:
'''
while True:
username = input('請(qǐng)輸入注冊(cè)的用戶名,或輸入q返回菜單:').strip()
if username == '':
print('用戶名為空,請(qǐng)重新輸入!')
elif username.upper() == 'Q':
break
else:
# 執(zhí)行判斷用戶名函數(shù)
result = registered_username(username)
if result:
password = input('請(qǐng)輸入您的注冊(cè)的密碼:').strip()
# 判斷密碼
if password == '':
print('密碼為空,請(qǐng)重新輸入!')
else:
# 執(zhí)行寫(xiě)入用戶列表文件函數(shù)
result = write_file(username, password)
if result:
print('注冊(cè)成功!,您的用戶名為: {}\n倒計(jì)時(shí)2秒返回菜單!'.format(username))
time.sleep(2)
user_menu()
else:
print('注冊(cè)失敗!請(qǐng)重試')
else:
print('用戶名已經(jīng)存在,請(qǐng)重新輸入!')
5.判斷注冊(cè)用戶名是否可用
def registered_username(username):
'''
#判斷注冊(cè)用戶名是否可用
:param username: 用戶名
:return: True 可用(用戶不存在) False 不可用(用戶已存在)
'''
# 純用戶名列表,不包含密碼
user_list = []
with open(file_name, encoding='utf-8') as f1:
for i in f1:
# 去空格,以空格切割,轉(zhuǎn)換為列表
li = i.strip().split() # [張三,123]
# 將用戶名追加到列表中
user_list.append(li[0])
# 判斷用戶名是否存在列表中
if username in user_list:
# 返回False
return False
else:
return True
6.寫(xiě)入用戶列表文件
def write_file(username,password):
'''
#寫(xiě)入用戶列表文件
:param username: 用戶名
:param password: 密碼
:return: True 寫(xiě)入成功 False 寫(xiě)入失敗
'''
with open(file_name, encoding='utf-8', mode='a') as f2:
f2.write('\n{} {}'.format(username, password))
return True
7.登錄邏輯
def login(count=0,max=3):
'''
登錄邏輯
:param count: 初始失敗次數(shù)
:param max: 最大失敗次數(shù)
:return:
'''
while count < max:
count += 1
username = input('請(qǐng)輸入用戶名:').strip()
password = input('請(qǐng)輸入密碼:').strip()
# 執(zhí)行驗(yàn)證用戶名和密碼函數(shù)
result = username_password(username,password)
if result:
print('登陸成功\n倒計(jì)時(shí)1秒返回菜單!')
time.sleep(1)
user_menu()
break
else:
print('用戶名或密碼錯(cuò)誤,還剩余{}次機(jī)會(huì)!'.format(max - count))
# 返回主菜單
user_menu()
8.判斷用戶名和密碼是否匹配
def username_password(username,password):
'''
#判斷用戶名和密碼是否匹配
:param username: 用戶名
:param password: 密碼
:return: True 匹配成功 False 匹配失敗
'''
# print(username,password)
with open(file_name, encoding='utf-8', mode='r') as f3:
for i in f3:
# print(i)
# 去空格,以空格切割,轉(zhuǎn)換為列表
li = i.strip().split() # [張三,123]
# 判斷用戶名和密碼是否匹配
if username == li[0] and password == li[1]:
result = True
# 當(dāng)找到匹配時(shí),跳出循環(huán)
break
else:
result = False
# 當(dāng)整個(gè)用戶列表遍歷完成之后,再return
return result
最終完整代碼如下:
# -*- coding: utf-8 -*-
import time,os
#文件名
file_name = 'user_list.txt'
def file_exists(*args,**kwargs):
'''
# 判斷用戶列表文件是否存在
:return: True 存在 False 不存在
'''
# 判斷文件是否存在
if os.path.exists(file_name):
return True
else:
with open(file_name, encoding='utf-8', mode='w') as mk:
mk.write('張三 123')
return False
def registered_username(username):
'''
#判斷注冊(cè)用戶名是否可用
:param username: 用戶名
:return: True 可用(用戶不存在) False 不可用(用戶已存在)
'''
# 純用戶名列表,不包含密碼
user_list = []
with open(file_name, encoding='utf-8') as f1:
for i in f1:
# 去空格,以空格切割,轉(zhuǎn)換為列表
li = i.strip().split() # [張三,123]
# 將用戶名追加到列表中
user_list.append(li[0])
# 判斷用戶名是否存在列表中
if username in user_list:
# 返回False
return False
else:
return True
def write_file(username,password):
'''
#寫(xiě)入用戶列表文件
:param username: 用戶名
:param password: 密碼
:return: True 寫(xiě)入成功 False 寫(xiě)入失敗
'''
with open(file_name, encoding='utf-8', mode='a') as f2:
f2.write('\n{} {}'.format(username, password))
return True
def username_password(username,password):
'''
#判斷用戶名和密碼是否匹配
:param username: 用戶名
:param password: 密碼
:return: True 匹配成功 False 匹配失敗
'''
# print(username,password)
with open(file_name, encoding='utf-8', mode='r') as f3:
for i in f3:
# print(i)
# 去空格,以空格切割,轉(zhuǎn)換為列表
li = i.strip().split() # [張三,123]
# 判斷用戶名和密碼是否匹配
if username == li[0] and password == li[1]:
result = True
# 當(dāng)找到匹配時(shí),跳出循環(huán)
break
else:
result = False
# 當(dāng)整個(gè)用戶列表遍歷完成之后,再return
return result
def register(*args,**kwargs):
'''
注冊(cè)邏輯
:return:
'''
while True:
username = input('請(qǐng)輸入注冊(cè)的用戶名,或輸入q返回菜單:').strip()
if username == '':
print('用戶名為空,請(qǐng)重新輸入!')
elif username.upper() == 'Q':
break
else:
# 執(zhí)行判斷用戶名函數(shù)
result = registered_username(username)
if result:
password = input('請(qǐng)輸入您的注冊(cè)的密碼:').strip()
# 判斷密碼
if password == '':
print('密碼為空,請(qǐng)重新輸入!')
else:
# 執(zhí)行寫(xiě)入用戶列表文件函數(shù)
result = write_file(username, password)
if result:
print('注冊(cè)成功!,您的用戶名為: {}\n倒計(jì)時(shí)2秒返回菜單!'.format(username))
time.sleep(2)
user_menu()
else:
print('注冊(cè)失敗!請(qǐng)重試')
else:
print('用戶名已經(jīng)存在,請(qǐng)重新輸入!')
def login(count=0,max=3):
'''
登錄邏輯
:param count: 初始失敗次數(shù)
:param max: 最大失敗次數(shù)
:return:
'''
while count < max:
count += 1
username = input('請(qǐng)輸入用戶名:').strip()
password = input('請(qǐng)輸入密碼:').strip()
# 執(zhí)行驗(yàn)證用戶名和密碼函數(shù)
result = username_password(username,password)
if result:
print('登陸成功\n倒計(jì)時(shí)1秒返回菜單!')
time.sleep(1)
user_menu()
break
else:
print('用戶名或密碼錯(cuò)誤,還剩余{}次機(jī)會(huì)!'.format(max - count))
# 返回主菜單
user_menu()
def user_menu(*args,**kwargs):
'''
# 用戶菜單
'''
# 判斷文件是否存在,不存在創(chuàng)建文件
file_exists()
# 循環(huán)
while True:
# 打印菜單
menu = ['注冊(cè)', '登錄', '退出']
print('bbs系統(tǒng)'.center(25, '#'))
for i in range(len(menu)):
print('{}\t{}'.format(i + 1, menu[i]))
print(''.center(27, '#'))
number = input('請(qǐng)選擇序號(hào): ').strip()
if number == '1':
# 執(zhí)行注冊(cè)程序
register()
elif number == '2':
# 執(zhí)行登錄程序
login()
elif number == '3':
exit()
else:
print('輸入錯(cuò)誤,請(qǐng)重新輸入!')
# 執(zhí)行菜單
user_menu()
執(zhí)行輸出:
總結(jié)
以上是生活随笔為你收集整理的python带参数装饰器 函数名_python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: iOS 17支持哪些机型iOS 17支持
- 下一篇: python读取sqlserver的数据