一次错综离奇的super调用的None参数super() argument 1 must be type, not None
最近在python的代碼中,使用裝飾器的功能以后,遇到了一個(gè)有意思的錯(cuò)誤,記錄下與大家分享一下,希望大家不會(huì)犯同樣的錯(cuò)誤。
大致代碼如下:
fn_list = {}def decrator(fn):fn_list[fn.__name__] = fn@decrator def print_test(index):print(index)return 'success'@decrator class TestClass(object):def __init__(self):super(TestClass, self).__init__()print("finish init func")ouput_result = fn_list['print_test']('1234') print(ouput_result) test_instance = fn_list['TestClass']()運(yùn)行的時(shí)候,在創(chuàng)建TestClass的對(duì)象的時(shí)候,報(bào)錯(cuò)如下:
in __init__
super() argument 1 must be type, not None
檢查代碼的時(shí)候,先查看了fn_list[‘TestClass’]確實(shí)指向了對(duì)應(yīng)的類,不是None。
在__init__函數(shù)中,輸出self,發(fā)現(xiàn)是對(duì)應(yīng)類的對(duì)象,然后輸出TestClass,發(fā)現(xiàn)是None。
但是調(diào)用同樣用裝飾器裝飾的print_test沒有發(fā)生問題。
其實(shí)問題就出在裝飾器函數(shù)上,裝飾器的作用其實(shí)就是在對(duì)象(例如函數(shù),類)定義的時(shí)候 改變這個(gè)對(duì)象后續(xù)調(diào)用過(guò)程中的行為,又不改變這個(gè)對(duì)象內(nèi)部代碼。
以裝飾某一個(gè)函數(shù)為例子,比如裝飾器是decrator函數(shù),裝飾在print_test函數(shù),那么在函數(shù)print_test定義的時(shí)候(此時(shí)函數(shù)print_test不被調(diào)用),首先調(diào)用了一次print_test = decorator(print_test),對(duì)于print_test的函數(shù)進(jìn)行定義。那么,此時(shí)指向print_test對(duì)象的指針,已經(jīng)被替換成了指向decorator(print_test)的指針。這里需要注意的是,此時(shí)print_test函數(shù)已經(jīng)被覆蓋成了新的函數(shù)decorator(print_test),即調(diào)用decorator函數(shù),并將print_test作為參數(shù)傳入,得到的返回值,即print_test = decorator(print_test)。
詳細(xì)的了解了裝飾器的工作機(jī)制,就不難理解上述問題的出現(xiàn)了。
首先,為什么調(diào)用print_test會(huì)有正確的結(jié)果,這個(gè)是因?yàn)樵谘b飾器中,保存了print_test的調(diào)用入口,并且是通過(guò)這個(gè)入口調(diào)用的(ouput_result = fn_list['print_test']('1234')
)。但是,如果直接調(diào)用print_test('1234'),會(huì)出錯(cuò)。
其次,創(chuàng)建對(duì)象為什么會(huì)報(bào)錯(cuò)。這個(gè)是因?yàn)?#xff0c;創(chuàng)建對(duì)象調(diào)用,從保留的正確入口進(jìn)行了調(diào)用(fn_list['TestClass']()),但是,在類初始化的__init__函數(shù)中,調(diào)用super的時(shí)候,是用的函數(shù)名稱TestClass進(jìn)行直接調(diào)用的,這個(gè)時(shí)候,其實(shí)TestClass已經(jīng)在定義的時(shí)候,因?yàn)檎{(diào)用TestClass = decorator(TestClass) 而變成了None(decorator沒有顯式指定返回值,所以為默認(rèn)返回值None),這樣就產(chǎn)生了最終的這個(gè)錯(cuò)綜離奇的報(bào)錯(cuò)。
太長(zhǎng)不看系列:
裝飾器原理,對(duì)于用裝飾器修飾的函數(shù)定義:
@decorator
def func():
pass
在定義時(shí),先調(diào)用了func = decorator(func),對(duì)于func進(jìn)行了定義的修改。
由于decorator在我的代碼中沒有顯式定義返回值,則使用的默認(rèn)返回值None。
于是所有被裝飾的函數(shù)和類,都被設(shè)置為None的變量。
修改辦法
def decrator(fn):fn_list[fn.__name__] = fnreturn fn總結(jié)
以上是生活随笔為你收集整理的一次错综离奇的super调用的None参数super() argument 1 must be type, not None的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle VM VirtualBox
- 下一篇: ME811 刷机