摘要:的被設(shè)定為裝飾器可以幫助我們檢查保證沒(méi)有重復(fù)值。錯(cuò)誤記錄等解釋器打印錯(cuò)誤棧的信息,程序也結(jié)束了。將通過(guò)配置記錄到日志文件中方便后續(xù)的排查。同理,指定后,和就不起作用了。啟動(dòng)的調(diào)試器,讓程序以單步方式運(yùn)行。
日常的寫在前面
難得的周末,有大段的時(shí)間可以用來(lái)學(xué)習(xí),體驗(yàn)就和工作日的晚上完全不一樣了。
好好的沉下心學(xué)習(xí)下~
即刻很喜歡了!
打打打雞血!!!!!!
面向?qū)ο蟾呒?jí)編程前天的定制類的__call__通過(guò)小佳揚(yáng)的一語(yǔ)驚醒夢(mèng)中人,就是把對(duì)象函數(shù)化了。
感覺(jué)有點(diǎn)囫圇吞棗,看完教程后要還好好地歸納下。
定義常量時(shí)候使用,例如定義月份。
JAN = 1 FEB = 2 MAR = 3 ... NOV = 11 DEC = 12
但是此時(shí)的類型是int。
通過(guò)Python提供的Enum類來(lái)實(shí)現(xiàn)為枚舉類型定義一個(gè)class類型。
from enum import Enum Month = Enum("Month", ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
這樣就獲得了Month類型的枚舉類,可以使用Month.Jan來(lái)引用一個(gè)常量,或者枚舉成員。
for name, member in Month.__members__.items(): print(name, "=>", member, ",", member.value)
value屬性是自動(dòng)賦給成員的值,默認(rèn)從1開(kāi)始計(jì)數(shù)。
如果需要更精確地控制枚舉類型,可以從Enum派生出自定義類。
from enum import Enum, unique @unique class Weekday(Enum): Sun = 0 # Sun的value被設(shè)定為0 Mon = 1 Tue = 2 Wed = 3 Thu = 4 Fri = 5 Sat = 6
@unique裝飾器可以幫助我們檢查保證沒(méi)有重復(fù)值。
使用元類 type()動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言最大的不同,就是函數(shù)和類的定義,不是編譯時(shí)定義的,而是運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建的。
type()函數(shù)可以查看類型或者變量的類型,class的類型就是type。
而且type()函數(shù)既可以返回一個(gè)對(duì)象的類型,又可以創(chuàng)建出新的類型。
#用type()函數(shù)創(chuàng)造出hello類 def fn(self, name="world"): # 先定義函數(shù) print("Hello, %s." % name) Hello = type("Hello", (object,), dict(hello=fn))
用type()創(chuàng)建類,需要依次傳入三個(gè)參數(shù):
class的名稱;
繼承的父類集合,注意Python支持多重繼承,如果只有一個(gè)父類,別忘了tuple的單元素寫法;
class的方法名稱與函數(shù)綁定,這里我們把函數(shù)fn綁定到方法名hello上
這樣和直接定義class的寫法沒(méi)有差異,但是這樣的話就可以在代碼運(yùn)行的過(guò)程中,動(dòng)態(tài)創(chuàng)建類,這和靜態(tài)語(yǔ)言有很大不同。
metaclass除了使用type()動(dòng)態(tài)創(chuàng)建類以外,要控制類的創(chuàng)建行為,還可以使用metaclass。
先定義metaclass,就可以創(chuàng)建類,最后創(chuàng)建實(shí)例。
據(jù)說(shuō)很難理解的魔術(shù)代碼,還是認(rèn)真的努力理解下吧!
看下大牛的代碼!
這個(gè)metaclass可以給我們自定義的MyList增加一個(gè)add方法:
定義ListMetaclass,按照默認(rèn)習(xí)慣,metaclass的類名總是以Metaclass結(jié)尾,以便清楚地表示這是一個(gè)metaclass。
# metaclass是類的模板,所以必須從`type`類型派生: class ListMetaclass(type): def __new__(cls, name, bases, attrs): attrs["add"] = lambda self, value: self.append(value) return type.__new__(cls, name, bases, attrs)
有了ListMetaclass,我們?cè)诙x類的時(shí)候還要指示使用ListMetaclass來(lái)定制類,傳入關(guān)鍵字參數(shù)metaclass:
class MyList(list, metaclass=ListMetaclass): pass
這樣MyList創(chuàng)建的時(shí)候,需要通過(guò)ListMetaclass.__new__()來(lái)創(chuàng)建。
__new__()方法接收到的參數(shù)依次是:
當(dāng)前準(zhǔn)備創(chuàng)建的類的對(duì)象;
類的名字;
類集成的父類集合;
類的方法集合。
而MyList()可以調(diào)用add方法,但普通list()就沒(méi)有。
list即類的對(duì)象。
這個(gè)復(fù)雜的有點(diǎn){{BANNED}}的定義方式,在一些場(chǎng)景下,例如ORM的編寫中,會(huì)很有用。
ORM全稱“Object Relational Mapping”,即對(duì)象-關(guān)系映射,就是把關(guān)系數(shù)據(jù)庫(kù)的一行映射為一個(gè)對(duì)象,也就是一個(gè)類對(duì)應(yīng)一個(gè)表,這樣,寫代碼更簡(jiǎn)單,不用直接操作SQL語(yǔ)句。
這塊有點(diǎn)復(fù)雜,雖然看懂了,但是還要好好琢磨下
錯(cuò)誤、調(diào)試和測(cè)試 錯(cuò)誤處理高級(jí)語(yǔ)言都內(nèi)置了一套try...except...finally...的錯(cuò)誤處理機(jī)制,Python小可愛(ài)也有。
try
當(dāng)有錯(cuò)誤時(shí)候,會(huì)打斷代碼的進(jìn)行,跳轉(zhuǎn)到except處,一旦有finally的話就一定會(huì)執(zhí)行,無(wú)論有沒(méi)有發(fā)生錯(cuò)誤。
可以有多個(gè)except獲取不同的錯(cuò)誤,但是注意父類和子類的問(wèn)題,如果一旦包括了父類錯(cuò)誤,子類所在的except就不會(huì)被執(zhí)行。
except后也可以加else語(yǔ)句,當(dāng)沒(méi)有錯(cuò)誤發(fā)生的時(shí)候,會(huì)執(zhí)行else語(yǔ)句。
Python所有的錯(cuò)誤都是從BaseException類派生的,常見(jiàn)的錯(cuò)誤類型和繼承關(guān)系有這些:
https://docs.python.org/3/lib...
也就是說(shuō),不需要在每個(gè)可能出錯(cuò)的地方去捕獲錯(cuò)誤,只要在合適的層次去捕獲錯(cuò)誤就可以了。這樣一來(lái),就大大減少了寫try...except...finally的麻煩。
調(diào)用棧如果錯(cuò)誤沒(méi)有被捕獲,它就會(huì)一直往上拋,最后被Python解釋器捕獲,打印一個(gè)錯(cuò)誤信息,然后程序退出。
所以找錯(cuò)誤棧的時(shí)候,一定要找到準(zhǔn)確的最里面那層。
等Python解釋器打印錯(cuò)誤棧的信息,程序也結(jié)束了。
既然可以捕獲,就在捕獲的同時(shí)打印錯(cuò)誤信息并分析原因,讓程序繼續(xù)下去。
Python內(nèi)置的logging可以很容易的記錄錯(cuò)誤信息。
# err_logging.py import logging def foo(s): return 10 / int(s) def bar(s): return foo(s) * 2 def main(): try: bar("0") except Exception as e: logging.exception(e) main() print("END")
這樣打印完錯(cuò)誤信息后還會(huì)打印END,即運(yùn)行了后續(xù)的代碼。
將logging通過(guò)配置記錄到日志文件中方便后續(xù)的排查。
捕獲的錯(cuò)誤其實(shí)是錯(cuò)誤class的一個(gè)實(shí)例,錯(cuò)誤也是需要定以后才能拋出然后被捕獲到的。
如果要拋出錯(cuò)誤,首先根據(jù)需要,可以定義一個(gè)錯(cuò)誤的class,選擇好繼承關(guān)系,然后,用raise語(yǔ)句拋出一個(gè)錯(cuò)誤的實(shí)例.
# err_raise.py class FooError(ValueError): pass def foo(s): n = int(s) if n==0: raise FooError("invalid value: %s" % s) return 10 / n foo("0")
另一種拋出錯(cuò)誤的例子如下。
# err_reraise.py def foo(s): n = int(s) if n==0: raise ValueError("invalid value: %s" % s) return 10 / n def bar(): try: foo("0") except ValueError as e: print("ValueError!") raise #錯(cuò)誤又被拋出 bar()
這種方式也很常見(jiàn),在拋出問(wèn)題后繼續(xù)拋回上一級(jí),由頂曾調(diào)用者進(jìn)行處理。
raise語(yǔ)句如果不帶參數(shù),就會(huì)把當(dāng)前錯(cuò)誤原樣拋出。
此外,在except中raise一個(gè)Error,還可以把一種類型的錯(cuò)誤轉(zhuǎn)化成另一種類型。
用print()打印有問(wèn)題的變量
麻煩在還得刪掉或注釋掉相應(yīng)語(yǔ)句
凡是可以用print打印的地方,都可以用asset斷言來(lái)代替。
def foo(s): n = int(s) assert n != 0, "n is zero!"#判斷此處n!=0是否為True,如果非則拋出AssertionError return 10 / n def main(): foo("0")
可以在啟動(dòng)Python解釋器的時(shí)候關(guān)閉assert
$python -0logging
同樣是替換print,logging不會(huì)拋出錯(cuò)誤,而且可以輸出到文件。
import logging logging.basicConfig(level=logging.INFO) s = "0" n = int(s) logging.info("n = %d" % n) print(10 / n)
這就是logging的好處,它允許你指定記錄信息的級(jí)別,有debug,info,warning,error等幾個(gè)級(jí)別,當(dāng)我們指定level=INFO時(shí),logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。這樣一來(lái),你可以放心地輸出不同級(jí)別的信息,也不用刪除,最后統(tǒng)一控制輸出哪個(gè)級(jí)別的信息。pdb
logging的另一個(gè)好處是通過(guò)簡(jiǎn)單的配置,一條語(yǔ)句可以同時(shí)輸出到不同的地方,比如console和文件。
啟動(dòng)Python的調(diào)試器pdb,讓程序以單步方式運(yùn)行。
pdb.set_trace()這個(gè)方法也是用pdb,但是不需要單步執(zhí)行,我們只需要import pdb,然后,在可能出錯(cuò)的地方放一個(gè)pdb.set_trace(),就可以設(shè)置一個(gè)斷點(diǎn)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42942.html
摘要:直接抄其中一份的結(jié)論吧各地區(qū)招聘公司數(shù)量和平均待遇。可以看出不論是招聘公司的數(shù)據(jù)還是平均待遇水平主要都是北上廣深杭州占優(yōu)勢(shì)。但事實(shí)證明,總是要有一些代價(jià)的。要學(xué)會(huì)看報(bào)錯(cuò)信息。函數(shù)定義結(jié)束后需要按兩次回車重新回到提示符下。 又是寫在前面的亂七八糟 持續(xù)學(xué)習(xí)的第三天了,持續(xù)學(xué)習(xí)是一個(gè)不容易培養(yǎng)的好習(xí)慣,但是堅(jiān)持就是勝利嘛~昨天因?yàn)橐稽c(diǎn)點(diǎn)事情,所以沒(méi)能學(xué)習(xí)很長(zhǎng)時(shí)間,今天要補(bǔ)回來(lái)。周末要搬家,...
摘要:寫在前面今天沒(méi)有叨逼叨但是又一次錯(cuò)過(guò)了競(jìng)賽愛(ài)睡覺(jué)的小李下周要上班,下下周一定要參加了握拳認(rèn)真做題的分割線第一題兩地調(diào)度公司計(jì)劃面試人。第人飛往市的費(fèi)用為,飛往市的費(fèi)用為。示例輸入輸出解釋第一個(gè)人去市,費(fèi)用為。 寫在前面 今天沒(méi)有叨逼叨...但是又一次錯(cuò)過(guò)了競(jìng)賽...愛(ài)睡覺(jué)的小李...下周要上班,下下周一定要參加了(握拳 認(rèn)真做題的分割線 第一題 1029. 兩地調(diào)度公司計(jì)劃面試2N人。...
摘要:第二題漢明距離難度簡(jiǎn)單兩個(gè)整數(shù)之間的漢明距離指的是這兩個(gè)數(shù)字對(duì)應(yīng)二進(jìn)制位不同的位置的數(shù)目。給出兩個(gè)整數(shù)和,計(jì)算它們之間的漢明距離。第三題買賣股票的最佳時(shí)機(jī)難度簡(jiǎn)單給定一個(gè)數(shù)組,它的第個(gè)元素是一支給定股票第天的價(jià)格。 寫在前面 這幾天斷斷續(xù)續(xù)做了題目,也在慢慢體會(huì)一些數(shù)據(jù)思維。終于不用邊做視頻邊寫題目啦~開(kāi)心~把這幾天的題解發(fā)一下~ 認(rèn)真做題的分割線 第一題 977. 有序數(shù)組的平方難度...
摘要:給定的字符串只含有小寫英文字母,并且長(zhǎng)度不超過(guò)。其他這題了,要重做看了其他的人的題解,使用的是無(wú)限逼近中位值的辦法,理論基礎(chǔ)應(yīng)該是泰勒公式。萬(wàn)萬(wàn)沒(méi)想到居然用到了泰勒公式手工執(zhí)行了下算法,反而理解的更快,但是泰勒公式還得再?gòu)?fù)習(xí)下。 寫在前面的話 今天持續(xù)做題ing,python有意思~今天的題有點(diǎn)虐心...興許是我太笨了...會(huì)努力學(xué)習(xí)的!動(dòng)態(tài)規(guī)劃我來(lái)啦~ 開(kāi)始做題 第一題 459. 重...
摘要:在拖完地板之后,想想還是補(bǔ)上今天的題解吧感謝小佳揚(yáng)推薦的題目,默默的復(fù)習(xí)了一把遞歸第一題難度中等實(shí)現(xiàn),即計(jì)算的次冪函數(shù)。因?yàn)槭谴蝺纾绻苯友h(huán),復(fù)雜度就是了。次冪可以拆解為的方式。每次拆解,最后最小的單位應(yīng)該為。 寫在前面 年前嘛,就是各種渙散的狀態(tài)。在拖完地板之后,想想還是補(bǔ)上今天的題解吧~感謝小佳揚(yáng)推薦的題目,默默的復(fù)習(xí)了一把遞歸~ 第一題 50. Pow(x, n)難度:中等 ...
閱讀 734·2023-04-25 20:32
閱讀 2306·2021-11-24 10:27
閱讀 4541·2021-09-29 09:47
閱讀 2257·2021-09-28 09:36
閱讀 3660·2021-09-22 15:27
閱讀 2779·2019-08-30 15:54
閱讀 385·2019-08-30 11:06
閱讀 1282·2019-08-30 10:58