裝飾器是通過(guò)裝飾器函數(shù)修改原函數(shù)的一些功能而不需要修改原函數(shù),在很多場(chǎng)景可以用到它,比如① 執(zhí)行某個(gè)測(cè)試用例之前,判斷是否需要登錄或者執(zhí)行某些特定操作;② 統(tǒng)計(jì)某個(gè)函數(shù)的執(zhí)行時(shí)間;③ 判斷輸入合法性等。合理使用裝飾器可以極大地提高程序的可讀性以及運(yùn)行效率。本文將介紹Python裝飾器的使用方法。
成華網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)自2013年起到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
python裝飾器可以定義如下:
輸出:
python解釋器將test_decorator函數(shù)作為參數(shù)傳遞給my_decorator函數(shù),并指向了內(nèi)部函數(shù) wrapper(),內(nèi)部函數(shù) wrapper() 又會(huì)調(diào)用原函數(shù) test_decorator(),所以decorator()的執(zhí)行會(huì)先打印'this is wrapper',然后打印'hello world', test_decorator()執(zhí)行完成后,打印 'bye' ,*args和**kwargs,表示接受任意數(shù)量和類(lèi)型的參數(shù)。
裝飾器 my_decorator() 把真正需要執(zhí)行的函數(shù) test_decorator() 包裹在其中,并且改變了它的行為,但是原函數(shù) test_decorator() 不變。
一般使用如下形式使用裝飾器:
@my_decorator就相當(dāng)于 decorator = my_decorator(test_decorator) 語(yǔ)句。
內(nèi)置裝飾器@functools.wrap可用于保留原函數(shù)的元信息(將原函數(shù)的元信息,拷貝到對(duì)應(yīng)的裝飾器函數(shù)里)。先來(lái)看看沒(méi)有使用functools的情況:
輸出:
從上面的輸出可以看出test_decorator() 函數(shù)被裝飾以后元信息被wrapper() 函數(shù)取代了,可以使用@functools.wrap裝飾器保留原函數(shù)的元信息:
輸出:
裝飾器可以接受自定義參數(shù)。比如定義一個(gè)參數(shù)來(lái)設(shè)置裝飾器內(nèi)部函數(shù)的執(zhí)行次數(shù):
輸出:
Python 支持多個(gè)裝飾器嵌套:
裝飾的過(guò)程:
順序從里到外:
test_decorator('hello world') 執(zhí)行順序和裝飾的過(guò)程相反。
輸出:
類(lèi)也可以作為裝飾器,類(lèi)裝飾器主要依賴(lài)__call__()方法,是python中所有能被調(diào)用的對(duì)象具有的內(nèi)置方法(python魔術(shù)方法),每當(dāng)調(diào)用一個(gè)類(lèi)的實(shí)例時(shí),__call__()就會(huì)被執(zhí)行一次。
下面的類(lèi)裝飾器實(shí)現(xiàn)統(tǒng)計(jì)函數(shù)執(zhí)行次數(shù):
輸出:
下面介紹兩種裝飾器使用場(chǎng)景
統(tǒng)計(jì)函數(shù)執(zhí)行所花費(fèi)的時(shí)間
輸出:
在使用某些web服務(wù)時(shí),需要先判斷用戶(hù)是否登錄,如果沒(méi)有登錄就跳轉(zhuǎn)到登錄頁(yè)面或者提示用戶(hù)登錄:
--THE END--
def change(str1):
new_str = str()
for i in range(len(str1)):
if(65 = ord(str1[i]) = 90):
a = str1[i].lower()
print(a,end='')
elif(97 = ord(str1[i]) = 122):
a = str1[i].upper()
print(a,end='')
else:
a = str1[i]
print(a,end='')
return new_str
str2 = str(input("要轉(zhuǎn)換的字符串:"))
print(change(str2))
1)doctest
使用doctest是一種類(lèi)似于命令行嘗試的方式,用法很簡(jiǎn)單,如下
復(fù)制代碼代碼如下:
def f(n):
"""
f(1)
1
f(2)
2
"""
print(n)
if __name__ == '__main__':
import doctest
doctest.testmod()
應(yīng)該來(lái)說(shuō)是足夠簡(jiǎn)單了,另外還有一種方式doctest.testfile(filename),就是把命令行的方式放在文件里進(jìn)行測(cè)試。
2)unittest
unittest歷史悠久,最早可以追溯到上世紀(jì)七八十年代了,C++,Java里也都有類(lèi)似的實(shí)現(xiàn),Python里的實(shí)現(xiàn)很簡(jiǎn)單。
unittest在python里主要的實(shí)現(xiàn)方式是TestCase,TestSuite。用法還是例子起步。
復(fù)制代碼代碼如下:
from widget import Widget
import unittest
# 執(zhí)行測(cè)試的類(lèi)
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget()
def tearDown(self):
self.widget.dispose()
self.widget = None
def testSize(self):
self.assertEqual(self.widget.getSize(), (40, 40))
def testResize(self):
self.widget.resize(100, 100)
self.assertEqual(self.widget.getSize(), (100, 100))
# 測(cè)試
if __name__ == "__main__":
# 構(gòu)造測(cè)試集
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase("testSize"))
suite.addTest(WidgetTestCase("testResize"))
# 執(zhí)行測(cè)試
runner = unittest.TextTestRunner()
runner.run(suite)
簡(jiǎn)單的說(shuō),1構(gòu)造TestCase(測(cè)試用例),其中的setup和teardown負(fù)責(zé)預(yù)處理和善后工作。2構(gòu)造測(cè)試集,添加用例3執(zhí)行測(cè)試需要說(shuō)明的是測(cè)試方法,在Python中有N多測(cè)試函數(shù),主要的有:
TestCase.assert_(expr[, msg])
TestCase.failUnless(expr[, msg])
TestCase.assertTrue(expr[, msg])
TestCase.assertEqual(first, second[, msg])
TestCase.failUnlessEqual(first, second[, msg])
TestCase.assertNotEqual(first, second[, msg])
TestCase.failIfEqual(first, second[, msg])
TestCase.assertAlmostEqual(first, second[, places[, msg]])
TestCase.failUnlessAlmostEqual(first, second[, places[, msg]])
TestCase.assertNotAlmostEqual(first, second[, places[, msg]])
TestCase.failIfAlmostEqual(first, second[, places[, msg]])
TestCase.assertRaises(exception, callable, ...)
TestCase.failUnlessRaises(exception, callable, ...)
TestCase.failIf(expr[, msg])
TestCase.assertFalse(expr[, msg])
TestCase.fail([msg])
比較省事的辦法是用time模塊的strptime方法來(lái)解析日期字符串成為時(shí)間對(duì)象,然后再把年月日部分提取出來(lái),最后生成datetime.date對(duì)象。
#?方法1,?用time模塊的strptime方法來(lái)解析日期字符串成為時(shí)間對(duì)象
import?time,?datetime
date_str?=?'2017-10-19'
fmt?=?'%Y-%m-%d'
time_tuple?=?time.strptime(date_str,?fmt)
year,?month,?day?=?time_tuple[:3]
a_date?=?datetime.date(year,?month,?day)
print(a_date,?type(a_date))
#?方法2,?直接把日期字符串拆分轉(zhuǎn)換成?年/月/日?對(duì)應(yīng)的整數(shù)
import?datetime
date_str?=?'2017-10-19'
print(datetime.date(*map(int,?date_str.split('-'))))
第一段:
if(pos in fre_dist.keys()):
newvalue= fre_dist[pos]
第二段:
if(pos in fre_dist):
newValue=fre_dist[pos]
在處理3萬(wàn)條數(shù)據(jù)時(shí),第二段代碼的速度是第一段代碼速度的上千倍。
原因是:第一段代碼 fre_dist.keys()變成了list,python在檢索list的時(shí)候是比較慢的,第二段代碼 fre_dist是字典,python在檢索字典的時(shí)候速度是比較快的。
文章名稱(chēng):關(guān)于python測(cè)試函數(shù)時(shí)間的信息
標(biāo)題路徑:http://muchs.cn/article34/phgcpe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷(xiāo)型網(wǎng)站建設(shè)、網(wǎng)站改版、域名注冊(cè)、網(wǎng)站收錄、搜索引擎優(yōu)化、小程序開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)