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() ...
随机推荐
- zoj Simple Equation 数论
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5176 AX+BY = XY => (X-B)*(Y-A)= ...
- c语言 字符版 简易2048
花了两个多小时,用最蠢的方法写的……最简陋版…… 还不确定这么写逻辑对不对…… #include <iostream> #include <cstdio> #include & ...
- [struts2]struts结合ECharts的用法
<script src="http://echarts.baidu.com/build/dist/echarts-all.js"></script> < ...
- AJAX中的dataType(数据格式)-text、json
因为经常使用数据格式,所以将它封装成类,J这样就不会用到时就写了,直接调用写好的类就可以了 (1)dataType数据格式为:TEXT格式的数据是字符串的数据,在"ajax对数据进行删除和查 ...
- 错误: 找不到或无法加载主类 / Class not found
Java Resources文件上有红色感叹号存在 说明引入jar包存在错误,把引用错误的jar包去掉即可. 右键项目,Properties,Java Build Path,选中jar包remove, ...
- 【转】Sqlserver通过链接服务器访问Oracle的那些事儿!
原文:http://blog.sina.com.cn/s/blog_614b6f210100t80r.html 前言:1.不经历风雨,怎能见彩虹.2.充分利用BaiDu.google等搜索引擎查找资料 ...
- C# - 系统类 - String类
String类 ns:System String类封装了一系列不能被改变的Unicode字符序列 字符属于引用类型 但它又具有值类型的行为 固定不变意味着 一旦在托管堆中分配了一块内存来存储字符 字符 ...
- Ubuntu上架设PPPoE Server
一.安裝 PPPoE Server Software1)sudo apt-get install ppp2)rp-pppoe(非apt套件)wget -c http://www.roaringpeng ...
- 安装tensorflow
官网:http://tensorflow.org/安装步骤:1.sudo apt-get install python-pip python-dev python-virtualenv 3 co ...
- Oracle常用查询命令
Oracle查询完整格式如下: Select * from XX where XX group by YY having XX order by YY Select count(*), XX fr ...