疑惑 提出问题

前天同事问我一个问题,为什么这个脚本中的没有调用A 的__init__。脚本如下:

 class A(object):
def __init__(self, *args, **kwargs):
print "Call init from %s" %self.__class__ def __new__(cls, *args, **kwargs):
obj = object.__new__(cls, *args, **kwargs)
print "Call new from %s" %obj.__class__
return obj class B(object):
def __init__(self, *args, **kwargs):
print "Call init from %s" %self.__class__ def __new__(cls, *args, **kwargs):
obj = object.__new__(A, *args, **kwargs)
print "Call new from %s" %obj.__class__
return obj b = B()

其实我也比较奇怪,这个脚本写的比较奇怪,class B的的__new__返回了A的实例。也只是只执行了B的__new__方法,并没有执行A的__init__方法。

深入 迷失

遇到这个问题:

要深入首先查看了一下代码的编译后的python指令,查看B,是B的__init__方法的指令,

如上图,为了具体查看B()方法是如何调用,就添加了一个方法test_B。B()显示仅仅是两条指令

LOAD_GLOBAL

CALL_FUNCTION

查看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__。

问题解决了。。也学习了

要问我怎么知道在那个地方打断点,因为我已经看过了代码,只是理解没有那么深。

Python没有执行__init__的更多相关文章

  1. python中的__init__ 、__new__、__call__小结

    这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs)  创建对象时调用,返回 ...

  2. 从底层理解Python的执行

    摘要:是否想在Python解释器的内部晃悠一圈?是不是想实现一个Python代码执行的追踪器?没有基础?不要怕,这篇文章让你初窥Python底层的奥妙. [编者按]下面博文将带你创建一个字节码级别的追 ...

  3. python 中的__init__.py的用法与个人理解

    使用Python模块常见的情况是,事先写好A.py文件,需要import B.py文件时,先拷贝到当前目录,然后再import 这样的做法在程序量较小的情况下是可行的,如果程序交互复杂程度稍高,就很费 ...

  4. Python中的__init__()和__call__()函数

    Python中的__init__()和__call__()函数 在Python的class中有一些函数往往具有特殊的意义.__init__()和__call__()就是class很有用的两类特殊的函数 ...

  5. 【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)

    python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...

  6. python中的__init__(self)是什么意思呢

    python中的__init__(self)是什么意思呢 init(self)这个时类的初始化函数 1 2 3 4 class Obj: def init(self): print 1 obj = O ...

  7. 第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解

    第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解 一.    引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类 ...

  8. android模拟器(genymotion)+appium+python 框架执行基本原理(目前公司自己写的)

    android模拟器(genymotion)+appium+python 框架执行的基本过程: 1.Push.initDate(openid)方法     //业务数据初始化 1.1   v5db.p ...

  9. python中执行javascript代码

    python中执行javascript代码: 1.安装相应的库,我使用的是PyV8 2.import PyV8 ctxt = PyV8.JSContext()     ctxt.enter()     ...

随机推荐

  1. linux c 及 c++打印调用者函数caller function的方法,包括arm c平台

    一般情况下,编译的时候可能需要加 -g 选项,对于android ndk的-g选项添加请参见android类目下的另一篇文章. 以下文章中的__builtin_return_address() 宏,若 ...

  2. CodeForces 352C. Jeff and Rounding(贪心)

    C. Jeff and Rounding time limit per test:  1 second memory limit per test: 256 megabytes input: stan ...

  3. mysql常见优化,更多mysql,Redis,memcached等文章

    mysql常见优化 http://www.cnblogs.com/ggjucheng/archive/2012/11/07/2758058.html 更多mysql,Redis,memcached等文 ...

  4. webpack文档

    https://github.com/liunian/webpack-doc/blob/master/SUMMARY.md

  5. ASP.NET MVC- JSON ,Jquery, State management and Asynch controllers

    一.JSON  MVC And JQuery In case you are new to JSON please read this before moving ahead with this la ...

  6. cocos2d-x触屏事件(单点触屏)

    转自:http://blog.csdn.net/onerain88/article/details/7550009 一般经常用到的触屏的情况有两种:一种是Layer统一接收触屏消息,然后由程序根据需要 ...

  7. jQuery获取Select选中的Text和Value,根据Value值动态添加属性

    语法解释:1. $("#select_id").change(function(){//code...}); //为Select添加事件,当选择其中一项时触发2. var chec ...

  8. VC中获取窗体句柄的各种方法

    AfxGetMainWnd AfxGetMainWnd获取自身窗体句柄 HWND hWnd = AfxGetMainWnd()->m_hWnd; GetTopWindow 函数功能:该函数检查与 ...

  9. PPPoE Server Under Ubuntu/Debian

    http://imranasghar.blogspot.com/2009/05/pppoe-server-under-ubuntudebian.html ----------------------- ...

  10. Android 自定义View修炼-实现自定义圆形、圆角和椭圆ImageView(使用Xfermode图形渲染方法)

    一:简介: 在上一篇<Android实现圆形.圆角和椭圆自定义图片View(使用BitmapShader图形渲染方法)>博文中,采用BitmapShader方法实现自定义的圆形.圆角等自定 ...