2 回答

TA貢獻1934條經(jīng)驗 獲得超2個贊
第一部分:__new__默認情況下做什么?因為從頭開始創(chuàng)建對象是一項基本的、特定于實現(xiàn)的操作,所以定義object.__new__(與 定義的其余部分一樣)必然object是實現(xiàn)本身的一部分。這意味著您需要查看 CPython、PyPy、Cython 等的源代碼,以準確了解在 Python 的任何特定實現(xiàn)中如何管理對象創(chuàng)建。通常,這都是無法從 Python 本身直接訪問的低級簿記。
第二部分:如何__new__知道它得到了一個類參數(shù)?因為它假設它的第一個參數(shù)是一個類,如果調用者希望__new__正確工作,最好提供一個類!也就是說,沒有人真正明確地調用__new__過,除了通過super覆蓋__new__,然后,您必須確保cls自己明確地傳遞:
def __new__(cls, *args, **kwargs):
rv = super().__new__(cls, *args, **kwargs) # Not super().__new__(*args, **kwargs)
Foo其余時間,您不是通過Foo.__new__(Foo, ...)直接調用,而是通過調用類型本身來創(chuàng)建類的實例: Foo(...). 這是管理的,因為 's 元類的__call__方法Foo負責調用__new__你的。例如,您可以想象type.__call__大致定義為
# A regular instance method of type; we use cls instead of self to
# emphasize that an instance of a metaclass is a class
def __call__(cls, *args, **kwargs):
rv = cls.__new__(cls, *args, **kwargs) # Because __new__ is static!
if isinstance(rv, cls):
rv.__init__(*args, **kwargs)
return rv
請注意,__init__只有在__new__實際返回__new__首先調用的類的實例時才會調用。

TA貢獻1998條經(jīng)驗 獲得超6個贊
根據(jù)我的理解,默認實現(xiàn)__new__()是這樣的
class Default(object):
def __new__(cls, *args, **kwargs):
print("In new")
return super().__new__(cls,*args, **kwargs)
def __init__(self):
print("In init default")
default = Default()
print(type(default))
輸出
In new
In init default
<class '__main__.Default'>
基于文檔 https://docs.python.org/3/reference/datamodel.html#object。新的
典型的實現(xiàn)通過使用 super() 調用超類的__new__()方法來創(chuàng)建類的新實例。new (cls[, ...]) 帶有適當?shù)膮?shù),然后在返回之前根據(jù)需要修改新創(chuàng)建的實例。
該super().__new__()調用將創(chuàng)建實例并__init__()進行初始化。
下面的代碼顯示了不正確的覆蓋__new__()
class InccorectOverride(object):
def __new__(cls, *args, **kwargs):
pass
def __init__(self):
print("In init InccorectOverride")
a = InccorectOverride()
print(type(a))
輸出
<class 'NoneType'>
由于__new__()不返回實例,因此輸出值為 NoneType
希望這能回答你的問題
添加回答
舉報