Python没有执行__init__
疑惑 提出问题
前天同事问我一个问题,为什么这个脚本中的没有调用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__的更多相关文章
- python中的__init__ 、__new__、__call__小结
这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs) 创建对象时调用,返回 ...
- 从底层理解Python的执行
摘要:是否想在Python解释器的内部晃悠一圈?是不是想实现一个Python代码执行的追踪器?没有基础?不要怕,这篇文章让你初窥Python底层的奥妙. [编者按]下面博文将带你创建一个字节码级别的追 ...
- python 中的__init__.py的用法与个人理解
使用Python模块常见的情况是,事先写好A.py文件,需要import B.py文件时,先拷贝到当前目录,然后再import 这样的做法在程序量较小的情况下是可行的,如果程序交互复杂程度稍高,就很费 ...
- Python中的__init__()和__call__()函数
Python中的__init__()和__call__()函数 在Python的class中有一些函数往往具有特殊的意义.__init__()和__call__()就是class很有用的两类特殊的函数 ...
- 【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)
python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...
- python中的__init__(self)是什么意思呢
python中的__init__(self)是什么意思呢 init(self)这个时类的初始化函数 1 2 3 4 class Obj: def init(self): print 1 obj = O ...
- 第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解
第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解 一. 引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类 ...
- android模拟器(genymotion)+appium+python 框架执行基本原理(目前公司自己写的)
android模拟器(genymotion)+appium+python 框架执行的基本过程: 1.Push.initDate(openid)方法 //业务数据初始化 1.1 v5db.p ...
- python中执行javascript代码
python中执行javascript代码: 1.安装相应的库,我使用的是PyV8 2.import PyV8 ctxt = PyV8.JSContext() ctxt.enter() ...
随机推荐
- POJ-1151 Atlantis 矩形面积并
题目链接:http://poj.org/problem?id=1151 扫描线+离散+线段树,线段树每个节点保存的是离散后节点右边的线段. //STATUS:C++_AC_16MS_208KB #in ...
- POJ-2442 Sequence K路归并问题
题目链接:http://poj.org/problem?id=2442 问题一:K个有序表合成一个有序表,元素共有n个.用堆优化 问题二:两个序列的前n小的元素.堆优化. 这题就是问题二的扩展,每次处 ...
- jdbc内容
Jdbc:java数据库连接技术 主要执行操作:连接数据库,执行sql语句,处理结果 Class.forName("com.mysql.jdbc.Driver"); 执行jdbc驱 ...
- Cocos2d-x创建新工程
转自:http://www.cnblogs.com/andyque/archive/2011/09/27/2192920.html 而是新建一个工程.然后,我们不是copy文件夹.lib和dll了.我 ...
- jQuery Mobile方向感应事件
在现在的智能手机中,都有对方向变换的自动感知功能,比如当手机方向从水平方向切换到垂直方向时,则会触发该事件.在jQuery Mobile中,可以通过orientationchange事件进行绑定,并且 ...
- Java中各种排序算法
package org.rut.util.algorithm.support; import org.rut.util.algorithm.SortUtil; /** * @author treero ...
- cocosbuilder中的Callbacks和sound effects
cocosbuilder3中有增加了 Callback和sound effects 的timeline 这个东西用来在动画播放过程中控制音效和回调动作,非常方便 按住option键(alt), 点击t ...
- SVN源代码泄露
1. 联想b2b站SVN源代码泄露 开启Firefox,输入:b2b.thinkworldshop.com.cn/.svn/entries Webserver返回如下信息:
- 【iOS程序启动与运转】- RunLoop个人小结
学习iOS开发一般都是从UI开始的,从只知道从IB拖控件,到知道怎么在方法里写代码,然后会显示什么样的视图,产生什么样的事件,等等.其实程序从启动开始,一直都是按照苹果封装好的代码运行着,暴露的一些属 ...
- HDU1241(bfs)JAVA
import java.util.Scanner;public class Main1241 { public static void main(String[] args) { Scanner ci ...