关于python和C++中子类继承父类数据的问题
浏览:2676次 出处信息
今天在测试的时候发现一个很诡异的问题,语言描述不清楚,直接看代码吧。为了测试各种可能性,我写了两种类继承的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#!/usr/bin/python #-*- coding: UTF-8 -*- import re import sys import os import json import simplejson class Foo(object): _data = 1 def __init__(self,data): self._data = data def ShowFoo(self): print 'Foo',self._data class Bar(Foo): def __init__(self,data): super(Bar,self).__init__(data) def ShowBar(self): #会报错 #super(Bar,self)._data = 3 #Foo._data = 3 self.ShowFoo() print 'Bar',self._data print 'Bar',super(Bar,self)._data t = Bar(2) t.ShowBar() |
运行结果如下:
Foo 2 Bar 2 Bar 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#!/usr/bin/python #-*- coding: UTF-8 -*- import re import sys import os import json import simplejson class Foo: _data = 1 def __init__(self,data): self._data = data def ShowFoo(self): print 'Foo',self._data class Bar(Foo): def __init__(self,data): Foo.__init__(self,data) def ShowBar(self): #会更改父亲的数据 #Foo._data = 3 self.ShowFoo() print 'Bar',self._data print 'Bar',Foo._data t = Bar(2) t.ShowBar() |
运行结果如下:
Foo 2 Bar 2 Bar 1
不管是调用super(Bar,self),或者直接用Foo._data,获取到的父类的_data字段都是没有经过改变的,即初始化的1,反而是直接通过self._data获取的数据是经过改变的。由此可以推测出:
1 |
super(Bar,self).__init__(data) |
或者
1 |
Foo.__init__(self,data) |
改变的实际上是子类的数据,而并不是父类的数据。 但是到这里还不够,我们再把代码中注释掉的部分打开,即:
1 |
#super(Bar,self)._data = 3 |
和
1 |
#Foo._data = 3 |
则两份代码的运行结果:
Foo 2 Traceback (most recent call last): test.py|29| AttributeError: 'super' object has no attribute '_data'
和
Foo 2 Bar 2 Bar 3
可见没有问题。于是我们可以有如下结论:
1.父类里面的self._data 和 子类里面的 self._data是同一份数据
2.父类里面的self._data 和 子类的super(Bar,self)._data及Foo._data是不一样的
3.用super拿到的父类的数据是不可写的,倒是直接用父类名来更改数据。Foo._data的修改可以直接影响super(Bar,self)._data的值。
好吧,到这里我还是不想结束,我们用C++代码来测试一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#include <iostream> #include <string> #include <vector> #include <map> using namespace std; class Foo { public: Foo() { m_A = 1; } Foo(int a) { m_A = a; } int m_A; void ShowFoo() { cout<<m_A<<endl; } }; class Bar : public Foo { public: Bar(int a) : Foo(a) { } void ShowBar() { cout<<m_A<<endl; cout<<Foo::m_A<<endl; m_A = 100; ShowFoo(); cout<<m_A<<endl; cout<<Foo::m_A<<endl; Foo::m_A = 200; cout<<m_A<<endl; cout<<Foo::m_A<<endl; } }; int main(int argc, const char *argv[]) { Bar f(10); f.ShowBar(); return 0; } |
运行结果如下:
10 10 100 100 100 200 200
可见,对C++来说父类的m_A,子类的m_A,还有Foo::m_A都是一样的。
试验数据,不对之处还请大家不吝赐教~
附测试代码如下:下载
建议继续学习:
- 配置Nginx+uwsgi更方便地部署python应用 (阅读:105405)
- 如何成为Python高手 (阅读:53412)
- python实现自动登录discuz论坛 (阅读:31595)
- python编程细节──遍历dict的两种方法比较 (阅读:19005)
- 每个程序员都应该学习使用Python或Ruby (阅读:16276)
- 使用python爬虫抓站的一些技巧总结:进阶篇 (阅读:12122)
- 30分钟3300%性能提升――python+memcached网页优化小记 (阅读:12140)
- 我的PHP,Python和Ruby之路 (阅读:11851)
- Python处理MP3的歌词和图片 (阅读:8330)
- 关于使用python开发web应用的几个库总结 (阅读:7447)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:python三元运算符的正确方法
后一篇:使用 Perl 来开发 Nginx 的模块 >>
文章信息
- 作者:Dante 来源: Vimer
- 标签: python 继承
- 发布时间:2010-09-26 08:52:52
建议继续学习
近3天十大热文
- [45] 如何拿下简短的域名
- [45] IOS安全–浅谈关于IOS加固的几种方法
- [44] 图书馆的世界纪录
- [44] Oracle MTS模式下 进程地址与会话信
- [41] android 开发入门
- [41] 界面设计速成
- [41] 【社会化设计】自我(self)部分――欢迎区
- [39] 读书笔记-壹百度:百度十年千倍的29条法则
- [37] 视觉调整-设计师 vs. 逻辑
- [34] Go Reflect 性能