Python沒有執行__init__

疑惑 提出問題python

前天同事問我一個問題,爲何這個腳本中的沒有調用A 的__init__。腳本以下:學習

 1 class A(object):
 2     def __init__(self, *args, **kwargs):
 3         print "Call init from %s" %self.__class__
 4 
 5     def __new__(cls, *args, **kwargs):
 6         obj = object.__new__(cls, *args, **kwargs)
 7         print "Call new from %s" %obj.__class__
 8         return obj
 9 
10 
11 class B(object):
12     def __init__(self, *args, **kwargs):
13         print "Call init from %s" %self.__class__
14 
15     def __new__(cls, *args, **kwargs):
16         obj = object.__new__(A, *args, **kwargs)
17         print "Call new from %s" %obj.__class__
18         return obj
19 
20 b = B()

其實我也比較奇怪,這個腳本寫的比較奇怪,class B的的__new__返回了A的實例。也只是只執行了B的__new__方法,並無執行A的__init__方法。spa

深刻 迷失debug

遇到這個問題:調試

要深刻首先查看了一下代碼的編譯後的python指令,查看B,是B的__init__方法的指令,code

如上圖,爲了具體查看B()方法是如何調用,就添加了一個方法test_B。B()顯示僅僅是兩條指令blog

LOAD_GLOBALit

CALL_FUNCTIONio

查看Python源代碼,到編譯

PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
{
    ternaryfunc call;

    if ((call = func->ob_type->tp_call) != NULL) {
        PyObject *result;
        if (Py_EnterRecursiveCall(" while calling a Python object"))
            return NULL;
        result = (*call)(func, arg, kw);

**************看到這裏的時候有點迷失了,不知道tp_call是個什麼東西了,不肯定由typeobject來操做

(這個必須進行反省由於tp_call已已經明確了他來自哪裏)***************

調試 問題解決

 

最後使出了,大招對Python源代碼進行調試,在Linux上編譯python源代碼加上參數--with-debug, 而後執行gdb -ex r --args python test.py

在call_function,do_call,PyObject_Call 執行到以後,打上斷點。看到他運行到了

type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    obj = type->tp_new(type, args, kwds);
    if (obj != NULL) {
        if (!PyType_IsSubtype(obj->ob_type, type))
            return obj;

,這個時候我再去看代碼。發現哪裏已經寫好註釋了:

/* If the returned object is not an instance of type,
           it won't be initialized. */

好吧,很明確了了。沒有產生和class類型一致的instance,就不會進行初始化。即調用__init__。

問題解決了。。也學習了

要問我怎麼知道在那個地方打斷點,由於我已經看過了代碼,只是理解沒有那麼深。

相關文章
相關標籤/搜索