疑惑 提出问题

前天同事问我一个问题,为什么这个脚本中的没有调用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. 数值类对象:NSNumber,NSValue,NSNull

    基本,集合,复杂,对象 可用对象封装基本数值,然后将对象放入NSArray或NSDictionary 中. 用对象封装基本数值后,即可给其发送消息. 数值类型包括:NSNumber,NSValue,N ...

  2. EGOImageView的使用方法及注意事项

    1.下载EGOImageView及其相关的类库 EGOImageLoading 将EGOCache.EGOImageButton.EGOImageView.EGOImageLoader全部添加到工程下 ...

  3. PHP 判断用户是否手机访问

    $agent = check_wap(); if( $agent ) { header('Location: http://www.lewanau.com'); exit; } // check if ...

  4. mysql 学习心得 [学习]

    http://www.cnblogs.com/lyhabc/p/3822267.html

  5. vmtouch - the Virtual Memory Toucher

    https://hoytech.com/vmtouch/ [root@localhost ~]# git clone git://github.com/hoytech/vmtouch.git 正克隆到 ...

  6. RHCA442学习笔记-Unit11内存回收

       Unit 12 Memory Reclamation 内存回收            学习目标:                    A. 了解和调整内存回收                  ...

  7. 嵌入式Linux-objdump命令的使用

    objdump命令的使用 objdump命令是Linux下的反汇编目标文件或者可执行文件的命令,它还有其他作用,下面以ELF格式可执行文件test为例详细介绍: objdump -f test 显示t ...

  8. 触摸与手势学习-swift

    触摸是一个UITouch对象,该对象放在一个UIEvent中,每个UIEvent包含一个或多个UITouch对象,每个UITouch对象对应一个手指.系统将UIEvent发送到应用程序上,最后应用程序 ...

  9. 关于Java安全的书

    关于Java安全的书http://automationqa.com/forum.php?mod=viewthread&tid=2831&fromuid=21

  10. 开源安全测试 - BackTrack的应用

    开源安全测试 - BackTrack的应用: http://gdtesting.com/product.php?id=99