python __init__ __new___Python中的__init__和__new__介绍
介紹
首先我們要知道在面向對象編程中,實例化基本遵循創建實例對象、初始化實例對象、最后返回實例對象這么一個過程。
Python 中的 __new__ 方法負責創建一個實例對象,__init__ 方法負責將該實例對象進行初始化。
__new__() 是在新式類中新出現的方法,它作用在構造方法建造實例之前,可以這么理解,在 Python 中存在于類里面的構造方法 __init__() 負責將類的實例化,而在 __init__() 啟動之前,__new__() 決定是否要使用該 __init__() 方法,因為__new__() 可以調用其他類的構造方法或者直接返回別的對象來作為本類的實例。
__new__(),第一個參數cls是當前正在實例化的類。
class Example(object):
def __init__(self, *args, **kwargs):
pass
def __new__(cls, *args, **kwargs):
return object.__new__(cls, *args, **kwargs)
重點:
事實上如果(新式)類中沒有重寫__new__()方法,即在定義新式類時沒有重新定義__new__()時,Python默認是調用該類的直接父類的__new__()方法來構造該類的實例,如果該類的父類也沒有重寫__new__(),那么將一直按此規矩追溯至object的__new__()方法,因為object是所有新式類的基類。
而如果新式類中重寫了__new__()方法,那么你可以自由選擇任意一個的其他的新式類(必定要是新式類,只有新式類必定都有__new__(),因為所有新式類都是object的后代,而經典類則沒有__new__()方法)的__new__()方法來制造實例,包括這個新式類的所有前代類和后代類,只要它們不會造成遞歸死循環。
如果__new__()沒有返回cls(即當前類)的實例,那么當前類的__init__()方法是不會被調用的。如果__new__()返回其他類(新式類或經典類均可)的實例,那么只會調用被返回的那個類的構造方法。
__new__ 的作用
依照Python官方文檔的說法,__new__方法主要是當你繼承一些不可變的class時(比如int, str, tuple), 提供給你一個自定義這些類的實例化過程的途徑。還有就是實現自定義的metaclass。
首先我們來看一下第一個功能,具體我們可以用int來作為一個例子:
假如我們需要一個永遠都是正數的整數類型,通過集成int,我們可能會寫出這樣的代碼。
class ExampleInteger(int):
def __init__(self, value):
super(ExampleInteger, self).__init__(self, abs(value))
i = ExampleInteger(-3)
print i
但運行后會發現,結果根本不是我們想的那樣,我們任然得到了-3。這是因為對于int這種 不可變的對象,我們只有重載它的__new__方法才能起到自定義的作用。
這是修改后的代碼:
寫法一:
class ExampleInteger(int):
def __new__(cls, value):
return int.__new__(cls, abs(value))
i = ExampleInteger(-3)
print i
寫法二:
class ExampleInteger(int):
def __new__(cls, value):
return super(ExampleInteger, cls).__new__(cls, abs(value))
i = ExampleInteger(-3)
print i
通過重載__new__方法,我們實現了需要的功能。
super
super 是用來解決多重繼承問題的,直接用類名調用父類方法在使用單繼承的時候沒問題,但是如果使用多繼承,會涉及到查找順序(MRO)、重復調用(鉆石繼承)等種種問題。
總結
以上是生活随笔為你收集整理的python __init__ __new___Python中的__init__和__new__介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内存条大小:让你的电脑速度飞起来
- 下一篇: 内存大作战:G品牌VS B品牌,谁更快?