1. __new__ 和 __init__ 的區別 python 2.x 老式類(預設繼承type) 老式類中沒有__new__類方法(也就是說定義也不會執行,它不是老式類的類方法),__Init__ 作為構造函數,創建實例對象,並初始化。 過程: 類 => __init__() => 實例(sel ...
1. __new__ 和 __init__ 的區別
- python 2.x 老式類(預設繼承type)
class A: pass
-
- 老式類中沒有__new__類方法(也就是說定義也不會執行,它不是老式類的類方法),__Init__ 作為構造函數,創建實例對象,並初始化。
- 過程: 類 => __init__() => 實例(self)創建並初始化
- __init__: 不能有返回值
- python 3 和 python 2.x(顯示繼承新式類)
class A(object): pass
註: 在Python 3.x中沒有新式類和老式類之分,它們都繼承自'object' 類。因此可以不用顯示地指定其基類。'object'基類中擁有的方法和屬性可通用於所有的新式類。
-
- __new__ 為類方法,__init__ 為實例方法。__new__ 類方法創建實例對象,__init__ 實例方法初始化實例對象。
- 過程: 類 => __new__() => 實例對象 => __init__() => 初始化實例
- __init__ 不能有返回值,__new__ 必須有返回值且 object.__new__(cls) 或 super(類名, cls).__new__(cls),否則__init__ 不執行, object 與 super() 的區別:是否調用父類響應的方法
- __new__ 的返回值的object.__new__(cls)中不能有多餘的參數,比如: super(cls, cls).__new__(cls, *arg, **kwargs) 或 super().__new__(cls, *arg, **kwargs), *arg, **kwargs 添加應用__init__一致, super() 中的參數要不2個,要不沒有
class A(object): def __init__(self): print "A.__init__ called" # -> is actually never called def __new__(cls): print "A.__new__ called"
# return super(cls, cls).__new__(cls) # return object.__new__(cls) # 此兩種會執行 __init__
print A()
2. __get__, __getattr__, __getattribute__ 的區別
- 均是訪問屬性的方法,註意是屬性
- __getattr__(self, name) 當訪問屬性無法找到時,預設異常,可以自定義其返回值或者 AttributeError 異常
- __getattribute__(self, name): 2.7 在新式類中引入,如果定義,則無條件執行,如果實行不存在時,也不執行 __getattr__(相當於被屏蔽掉)
- __get__ (self, instance, owner) : 如果class定義了它,則這個class就可以稱為descriptor。owner是所有者的類,instance是訪問descriptor的實例,如果不是通過實例訪問,而是通過類訪問的話,instance則為None。(descriptor的實例自己訪問自己是不會觸發__get__,而會觸發__call__,只有descriptor作為其它類的屬性才有意義。)