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