摘要:列表越界的列表類似于動(dòng)態(tài)數(shù)組,沒有長(zhǎng)度的限制。比如對(duì)將要傳進(jìn)內(nèi)層函數(shù)的參數(shù)進(jìn)行檢測(cè)等,從而實(shí)現(xiàn)對(duì)參數(shù)的類型進(jìn)行限制。對(duì)二維列表的每一維列表進(jìn)行長(zhǎng)度限制,不足指定長(zhǎng)度,自動(dòng)補(bǔ)充指定元素。
前言
作為一名python的腦殘粉,請(qǐng)先跟我念一遍python大法好。
其作為動(dòng)態(tài)語(yǔ)言的靈活,簡(jiǎn)介的代碼,確實(shí)在某些情況下確實(shí)比其他編程語(yǔ)言要好。但你有沒有想過,有時(shí)這些靈活的語(yǔ)法,可能會(huì)造成一些糟糕的體驗(yàn)。尤其是針對(duì)新手,python易上手不假,但動(dòng)態(tài)語(yǔ)言寫得項(xiàng)目規(guī)模一大,其實(shí)比相對(duì)嚴(yán)謹(jǐn)?shù)撵o態(tài)語(yǔ)言,更考驗(yàn)程序員的內(nèi)力。
哪怕你只是用過python寫過一些初等的項(xiàng)目,那你可能也體驗(yàn)過以下這種情況。
莫名其妙的傳錯(cuò)參數(shù)類型。
python不需要顯式聲明參數(shù)類型,同樣,什么樣的變量都可以往函數(shù)里扔,包括函數(shù)(python支持函數(shù)式編程),這容易出現(xiàn)一個(gè)問題,如果一個(gè)函數(shù)不是自己設(shè)計(jì)的,你很可能網(wǎng)里面?zhèn)髁隋e(cuò)誤類型的參數(shù)。當(dāng)然,這樣大多數(shù)觸發(fā)異常,因?yàn)閭麇e(cuò)類型意味著函數(shù)的一些操作該類型不支持。但有時(shí)傳了錯(cuò)誤的參數(shù)類型,卻并不會(huì)觸發(fā)異常(比如字符串相加和數(shù)字相加,以及一切對(duì)象的==判斷),不會(huì)觸發(fā)異常結(jié)果卻是錯(cuò)誤的,這就意味著出現(xiàn)了問題更難確定位置,甚至如果這個(gè)函數(shù)的返回值,再傳進(jìn)其他函數(shù)(假設(shè)叫B)時(shí),當(dāng)你發(fā)現(xiàn)得到結(jié)果錯(cuò)誤時(shí),你很可能以為是B函數(shù)的邏輯設(shè)計(jì)出現(xiàn)了錯(cuò)誤,從而花費(fèi)大量的時(shí)間在錯(cuò)誤的地方,使用python多數(shù)是對(duì)開發(fā)效率比較重要的場(chǎng)景,而很可能因?yàn)橐粋€(gè)粗心,使得寫代碼的時(shí)間短了,結(jié)果將時(shí)間都花在找BUG上了。
進(jìn)行操作之前忘記了轉(zhuǎn)型
典型的就是把參數(shù)類型為str與int相加?;蛘甙?b>str傳進(jìn)range()里面。
列表越界
python的列表類似于動(dòng)態(tài)數(shù)組,沒有長(zhǎng)度的限制。雖然大多數(shù)我們只需用for x in one_list即可完成對(duì)列表的訪問,而不需要去考慮列表的長(zhǎng)度。但其實(shí)還有一種情景,比如說一個(gè)列表(或者元組)中元素的次序是有意義的,比如說[name,age,sex]而且這可能是某個(gè)函數(shù)動(dòng)態(tài)生成的,比如爬蟲爬取網(wǎng)站后從里面挑選信息后返回,這時(shí),如果這個(gè)網(wǎng)站中age,sex的信息缺失,python可不會(huì)自動(dòng)補(bǔ)充None下去,至少我沒看見有人的函數(shù)或方法會(huì)考慮到這一點(diǎn),而是直接給你返回[name],而如果你需要獲取age,而直接訪問下標(biāo)為1的元素,則會(huì)觸發(fā)異常。
類似的還有種種,當(dāng)然并非不可解決,比如足夠多的assert和isinstance,足夠嚴(yán)謹(jǐn)?shù)倪壿嬙O(shè)計(jì),枯燥但很有必要的單元測(cè)試等等……但使用python很多時(shí)候就是為了加快開發(fā)效率,上面的這些措施顯然太過麻煩。
斷斷續(xù)續(xù)的寫了一兩天,弄了幾個(gè)裝飾器來解決這些問題,下面開始分享一下。
什么是裝飾器如何利用裝飾器限制函數(shù)的參數(shù)和返回值需要了解pythopn中裝飾器的基本概念,可以參考一下廖老師的py教程
點(diǎn)這里
使用裝飾器可以使得一個(gè)函數(shù)外面加上某些操作然后在重新返回到你定義的函數(shù)名字指定的對(duì)象上。
說實(shí)話,我很難用言語(yǔ)描述出這種關(guān)系,直接上代碼好了。
以使用裝飾器限制函數(shù)參數(shù)類型為例:
裝飾器的實(shí)現(xiàn)如下:
def type_limit(*typeLimit,**returnType): def test_value_type(func): def wrapper(*param,**kw): length = len(typeLimit) if length != len(param): raise LimitError("The list of typeLimit and param must have the same length") for index in range(length): t = typeLimit[index] p = param[index] if not isinstance(p,t): raise LimitError("The param %s should be %s,but it"s %s now!"%(str(p),type(t()),type(p))) res = func(*param,**kw) if "returnType" in returnType: limit = returnType["returnType"] if not isinstance(res,limit): raise LimitError("This function must return a value that is %s,but now it"s %s"%(limit,type(res) ) ) return res return wrapper return test_value_type
假設(shè)我希望實(shí)現(xiàn)一個(gè)函數(shù),實(shí)現(xiàn)兩數(shù)求和,為了避免傳進(jìn)去的是兩個(gè)字符串,造成字符串連接,我需要限制其類型都為int
這時(shí),我們可以這么做:
@type_limit(int,int) def test(x,y): return x+y
這個(gè)定義的過程發(fā)生了什么呢?上述代碼等價(jià)于
temp = type_limit(int,int) #temp = test_value_type test = temp(test) #這是,test已經(jīng)在原test上經(jīng)過修飾,指向wrapper
而在wrapper中,最終會(huì)返回調(diào)用原test的結(jié)果,這個(gè)裝飾器做的,只不過是在調(diào)用原test前,利用
isinstance進(jìn)行了一遍類型檢測(cè)而已。這樣,我們可以簡(jiǎn)單的模仿像java,C++這樣的靜態(tài)語(yǔ)言一樣,在聲明的時(shí)候就對(duì)參數(shù)類型進(jìn)行限制了。
理解這個(gè)裝飾器把握著一下幾點(diǎn):
函數(shù)可以作為變量使用,即可以作為參數(shù)和返回值
裝飾器利用了函數(shù)內(nèi)的函數(shù),可以訪問外層函數(shù)之間的一些變量從而對(duì)內(nèi)層函數(shù)進(jìn)行修飾。(比如對(duì)將要傳進(jìn)內(nèi)層函數(shù)的參數(shù)進(jìn)行檢測(cè)等),從而實(shí)現(xiàn)對(duì)參數(shù)的類型進(jìn)行限制。
理解這兩點(diǎn)后,你可以自由的修改和拓展這些裝飾器,如果你有更好的實(shí)現(xiàn),記得在github上pull給我哦,github地址稍后給出。
其他相關(guān)的限制除上述外,我還是實(shí)現(xiàn)了其他限制:
列表長(zhǎng)度的限制,不足指定長(zhǎng)度,自動(dòng)補(bǔ)充指定元素。
對(duì)二維列表的每一維列表進(jìn)行長(zhǎng)度限制,不足指定長(zhǎng)度,自動(dòng)補(bǔ)充指定元素。主要為某些算法進(jìn)行限制。
常量類Const,目測(cè)沒有什么用
對(duì)列表的每一元素的類型進(jìn)行限制
后記限于篇幅,其他的代碼不一一在這里介紹,關(guān)鍵思路在上文已給出,其余代碼開源在github上,如果需要,你可以直接拿去使用。不過記得不要濫用。
github地址
如有更好的建議和或不正確的地方,可以在本文或github下告知。
如有錯(cuò)別字……請(qǐng)忽略(^ ^)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/45429.html
摘要:的裝飾器中的同樣借鑒了這個(gè)語(yǔ)法糖,不過依賴于的方法。等同于也就是說,裝飾器是一個(gè)對(duì)類進(jìn)行處理的函數(shù)。別名或裝飾器在控制臺(tái)顯示一條警告,表示該方法將廢除。有了裝飾器,就可以改寫上面的代碼。 更多文章,請(qǐng)?jiān)贕ithub blog查看 在 ES6 中增加了對(duì)類對(duì)象的相關(guān)定義和操作(比如 class 和 extends ),這就使得我們?cè)诙鄠€(gè)不同類之間共享或者擴(kuò)展一些方法或者行為的時(shí)候,變得并...
摘要:屬性有三個(gè)裝飾器。當(dāng)屬性只有方法,則為只有只讀屬性。使用規(guī)則只讀屬性只有方法,在方法前加上可讀可寫屬性有和方法,在方法上使用屬性名。 @property @property是內(nèi)置的裝飾器,與普通裝飾器原理是一樣的,只不過返回的不是函數(shù),而是類對(duì)象. @property負(fù)責(zé)把一個(gè)方法變成屬性進(jìn)行調(diào)用,保證對(duì)參數(shù)進(jìn)行必要的檢查。 屬性有三個(gè)裝飾器:setter、getter、dele...
摘要:本章主要是對(duì)上一章類的補(bǔ)充。對(duì)于多態(tài)的補(bǔ)充子類可以被看成是父類的類型,但父類不能被看成是子類的類型。仍然以類為例,動(dòng)物里有哺乳動(dòng)物,卵生動(dòng)物,有能飛的動(dòng)物和不能飛的動(dòng)物,這是兩種大的分類方式。一般在中,以為結(jié)尾類的都作為接口。 《Python編程:從入門到實(shí)踐》筆記。本章主要是對(duì)上一章Python類的補(bǔ)充。 1. 從一個(gè)類派生出所有類 上一篇文章說道Python類的定義與繼承一般是如下...
摘要:內(nèi)置函數(shù)實(shí)現(xiàn)對(duì)可迭代對(duì)象進(jìn)行進(jìn)一步處理。文件文件的打開權(quán)限打開文件,文件不存在報(bào)異常寫入文件,文件不存在則創(chuàng)建。文件不存在則創(chuàng)建。追加文件,具有讀寫權(quán)限。 Python基礎(chǔ)類型: 1.Tuple元組,內(nèi)容不可改變,但是允許元素內(nèi)部存在list等類型的元素,并且允許改變列表的值,所謂內(nèi)容不可變指的是在內(nèi)存中指向的地址是不變的。 temp=(1,2,[3,4]) temp[-1]....
摘要:一般情況下,我們使用裝飾器提供的語(yǔ)法糖,來簡(jiǎn)化上面的寫法像上面的情況,可以動(dòng)態(tài)修改函數(shù)或類功能的函數(shù)就是裝飾器。本文標(biāo)題為會(huì)打扮的裝飾器本文鏈接為參考資料修飾器的函數(shù)式編程中的裝飾器介紹思誠(chéng)之道裝飾器入門與提高賴明星 裝飾器 我們知道,在 Python 中,我們可以像使用變量一樣使用函數(shù): 函數(shù)可以被賦值給其他變量 函數(shù)可以被刪除 可以在函數(shù)里面再定義函數(shù) 函數(shù)可以作為參數(shù)傳遞給另外...
閱讀 1182·2021-11-24 09:39
閱讀 3652·2021-09-02 15:21
閱讀 2191·2021-08-24 10:01
閱讀 749·2021-08-19 10:55
閱讀 2474·2019-08-30 15:55
閱讀 1239·2019-08-30 14:16
閱讀 3019·2019-08-29 15:17
閱讀 3267·2019-08-29 13:53