python的隐式指针特征

pointer是C/C++的里非常熟悉也容易令人困惑的一个功能点,python里的变量赋值一般表现也和指针类似,但是没有显式地语法指出,·在这里我用自己的理解做一个比喻来帮助大家理解。

当我们写下一行语句,比如a=1 (python)或者int a=1(C++),电脑内存到底做了什么呢?这里的数据“1”在电脑内存里实际上是一个二级制序列,任何数据最终都以这种形式存储。而序列储存的位置,则是这份数据的地址,这个地址在内存中,通过“a”这个代号来获取。

所以,如果把地址比作是一栋房子,数据就像是房子里装的家具,而房子门口的门牌号,就是地址的名字。只不过在程序里,一个房子可以有多个门牌号,共同指向同一个房子,但是不能有多个房子,共享同一个门牌号。

a=1,a=2,是更改了a对应房子里存储的东西(数据)

a=1,b=a,是赋予“1”这个数据所在的房子两块门牌号(a,b)

此时修改a,b任意变量名的值,a、b的值均被修改,换句话说,python赋值默认是指针赋值,但是在class内赋值、copy赋值例外。

python class及inheritance

为什么需要class?

答案是我们需要用数据结构来存储数据的关系,而不是记在脑子里,或者是靠修改变量名称。比如我们需要程序计算,高中生的各科成绩求和。显然,一个简单的sum函数可以完成这样的运算,再来一个for循环,对所有的学生都算一遍。但是这样做之后,我们无法知道把学生的名字、单科成绩、各科成绩对应起来,虽然他们在循环中的次序是对应的。如果代码里稍有不慎修改了成绩的原始排序,就会出现驴唇对马嘴的情况。

class 作为一种复杂的数据结构,能够帮我们记录下一个综合体及其各个属性的关系,以支持更复杂的操作。

此外还能够提高代码可读性,减少重复代码块粘贴,提高效率。

class 数据结构还能继承,不断延展功能的同时,不干扰旧的代码功能,用尽量少的代码支持更多操作。

基本语法

class A(object):def __init__(self):print('A init called')self.num=1class B(A):def __init__(self):print('B init called')A.__init__(self)    a=A()
b=B()
b.num 

首先我们定了一个class 结构A,它的初始化/构造函数(类似于C++里的constructor)打印一句话,并且给自己多了一个成员 num,值为1

然后定义了一个class 结构B,B继承了A,B的构造函数打印了一句话,然后调用了A的构造函数,这里的调用,等同于把A的_init_函数完全复制到B里,并且执行,也就是继承了A的init

结果是

A init called #a=A()

B init called#b=B()的构造函数print

A init called#b的init里 call A的init,并且给B增加了一个成员self.num

1 #b.num

更规范的继承写法

上边的例子中,在B的init我们指定继承A的init,形如baseclass._init_(self),这种写法在一层继承中没有问题,但是在多层继承中,会丧失灵活性,因为此时,parent class被hard-coded,而不是按照继承链自动追溯,丧失了灵活性。

参考这篇文章的例子

What is the difference between old style and new style classes in Python?​stackoverflow.com

class 

上边的代码中,Unsuperchild class的继承写法是固定的,和上边的class B一样。而superchild class的继承方法是使用了super(括号可以省略)关键词,两者都继承自somebaseclass。那么到底有什么后果呢?我们再加入一层继承

class InjectMe(SomeBaseClass):def __init__(self):print('InjectMe.__init__(self) called')super(InjectMe, self).__init__()class UnsuperInjector(UnsuperChild, InjectMe): passclass SuperInjector(SuperChild, InjectMe): pass

InjectMe class 也继承自somebaseclass。同时UnsuperInjector继承UnsuperChild,和InjectMe,SuperInjector继承SuperChild,和InjectMe

现在的继承关系有三级

somebaseclass (grandparent)

unsuperchild superchild InjectMe (parent)

unsuperinjector superinjector (child)

根据Method Resolution Order (MRO)法则,当我生成一个第三级class 的实例时,会按照“先左后右再向上”的顺序调用super

比如我创建一个UnsuperInjector的实例,它的左边parent是UnsuperChild,先调用了UnsuperChild的init,UnsuperChild的init里写了,固定调用sombaseclass 的init,因此,不用super()关键字继承时,会受到固定parent class的限制,不会再调用injectme class

 o = UnsuperInjector()
# 打印  UnsuperChild.__init__(self) called
#打印  SomeBaseClass.__init__(self) called

而如果run下边一句结果就不同

o2 = SuperInjector()
SuperChild.__init__(self) called
InjectMe.__init__(self) called
SomeBaseClass.__init__(self) called

SuperInjector上一级左边是SuperChild,SuperChild的init里有super().init,,右边是InjectMe,也有super().init,因此SuperChild的super 指向InjectMe,InjectMe的super指向SomeBaseClass,因此打印结果如上边代码块所示。

总结

在multiple inheritance模式下,super().继承方法能够避免固定继承导致其他parent class继承失效的问题,增加了代码灵活性。同时注意继承的顺序由MRO决定,遵循同级先左后右,再增加深度的原则。

python pointer_python 的隐式指针特征与class inheritance相关推荐

  1. python显示等待隐式等待

    在Selenium Webdriver中等待的方式简单可以概括为三种: 1.导入time包,调用time.sleep()的方法传入时间,这种方式也叫强制等待,固定死等一个时间 2.隐式等待,直接调用i ...

  2. python 中使用隐式循环快速求和

    如何快速的求出1到x的和呢?代码如下: NB(注意): # 后面的部分表示输出结果. class Debug:def calculateSum(self, size):return sum(range ...

  3. python隐式调用方法_Python为什么不隐式实现self

    Python为什么不隐式实现self Python中类的方法都需要显式的传入一个self占位参数,这让写过C#,Java,PHP,Javascript的我很是不习惯,但是Python这么吊,肯定是有他 ...

  4. python隐式等待_selenium中隐式等待和显示等待的区别

    Selenium显示等待和隐式等待的区别 1.selenium的显示等待 原理:显示等待,就是明确的要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,那 ...

  5. python数据拟合固定参数_如何将数据拟合到非理想二极管方程(隐式非线性函数)并检索参数 - python...

    散乱数据图 我需要将(x,y)-数据拟合到具有两个变量(x和y)的方程式中,并检索5个未知参数. 我正在编写一个脚本,以处理来自简单.txt文件的IV数据(电流电压),并将其拟合为称为非理想二极管方程 ...

  6. python对应的岗位_隐式相对导入如何在Python中工作?

    包是具有__init__.py文件的目录,是,并且在模块搜索路径上找到时作为模块加载.因此,如果父目录位于模块搜索路径上,则pkg只是一个可以导入并视为包的包. 但是通过将pkg / core / m ...

  7. python显示等待和隐式等待_荐selenium内的隐式等待和显示等待的区别

    selenium的页面等待有显示等待和隐式等待 大多数Web应用程序都是使用Ajax和Javascript开发的.当浏览器加载页面时,我们想要与之交互的元素可能以不同的时间间隔加载. 它不仅难以识别元 ...

  8. [转载] python隐式转换_Python | 数据类型的转换 显式转换 隐式转换

    参考链接: Python类型转换和类型转换 显式转换 # 首先对要转换的数据进行变量的声明 float_number = 1.5 int_number = 2 # 其他类型转换到字符串,使用的是str ...

  9. python中for循环求和_python使用隐式循环快速求和的实现示例

    如何快速的求出1到x的和呢?代码如下: NB(注意): # 后面的部分表示输出结果. class Debug: def calculateSum(self, size): return sum(ran ...

最新文章

  1. C语言中regex_error,为什么这个C 11 std :: regex示例抛出一个regex_error异常?
  2. 亚马逊面部识别闹大笑话:竟28名美国议员识别为罪犯
  3. 1.mongodb在centos上面安装
  4. 关于JavaScript为何要限制跨域访问
  5. Meta分析到底该怎么选题?
  6. 将函数实现放在头文件中
  7. linux树莓派mysql_树莓派4B(二):搭建LNMP(LINUX+NIGIX+MYSQL+PHP)+ Pi Dashboard
  8. 我的世界服务器抽奖系统怎么弄,我的世界自动识别货币抽奖机如何制作
  9. Tree Cutting HDU - 5909
  10. JavaScript中的数组创建
  11. 【三维深度学习】多视角立体视觉模型R-MVSNet
  12. 【Flink】JobException: Recovery is suppressed by NoRestartBackoffTimeStrategy
  13. 使用Jquery中ajax实现上传文件
  14. java serviceimple,java apiimpl怎么调用 service接口
  15. 【霜雪千年】MMD动作镜头下载
  16. linux socket监听端口,Linux-socket使用
  17. 查看计算机启动项命令,启动项指令命令有哪些?教你设置电脑Windows开机启动项命令...
  18. LC1665. 完成所有任务的最少初始能量(推公式贪心)
  19. 【实习日记】Linux-VM15-Ubuntu18.04 + 运行selenium实现文件下载
  20. XML是什么?有什么用?

热门文章

  1. 27 行代码开发一个最简单的 SAP ALV 报表
  2. SAP 电商云 Spartacus UI Proxy Facade 的一个实际例子
  3. SAP UI5 应用开发教程之十三 - 如何添加自定义 CSS 类
  4. SAP UI5 初学者教程之四:XML 视图初探试读版
  5. Angular 项目里的 tsconfig.json
  6. 如何基于Restful ABAP Programming模型开发并部署一个支持增删改查的Fiori应用
  7. 30分钟用Restful ABAP Programming模型开发一个支持增删改查的Fiori应用
  8. UI5 plugin - uploadCollection
  9. AWS的Elastic IP和Private IP的区别
  10. Useful code snippet to parse the key value pairs in URL