Python的这种设计是作者从Modula-3中借鉴来的,在后面使用的情况看来,这个设计也是比较成功的。我们对比Python和C++讨论一下这个问题:

Modula-3是上世纪80年代末数字设备公司(DEC)系统研究中心(SRC)和Olivetti研究中心(ORC)设计的一门语言。

尽管这门语言没有在业界广泛的应用起来,但这么语言对后面被发明的Java, Python, Caml, C# 都产生了很多的影响

1.首先,调用的时候要求指定"this",让我们更明确的区分调用的是一个成员变量、函数或者是一个局部变量、函数。

当我们读到self.x或者self.meth(),即使我们不知道class的定义也能100%确定这里调用的是一个成员变量或者方法。我们设想一下,在C++中,我们还可以通过查看并排除所有的局部变量的方式去确认变量是成员变量(假设全局变量很少见,即使出现也是"g_"这种很容易辨认的)。

而在Python中,由于变量不需要额外的定义,这个办法就失效了,唯一的办法就只有看class的定义,所以this就成了必须的。 很多C++和Java的编码规范中会规定成员函数或变量要有m_前缀,我们也可以看到这种编码规范是十分必要的。

2.其次,由于this这个对当前实例的强制显式引用,Python不需要引入任何新的语法就可以引用或者调用其它类(包括父类)的成员变量和函数。

在C++中,如果我们想要在子类中调用父类的函数,我们需要用到::这个运算符;在Python中我们这么写baseclass.methodname(self, <argument list>)。Python的这种语法在实现子类的__init__()时特别有用,例如我们经常需要在子类中override父类的函数并且调用父类函数自身。

3.最后,就是性能上的些许考量:在Python的语言定义中,局部变量就是在函数体中赋值,并且没有在全局显式的声明过的变量。

当然在语言设计上,我们有很多的办法去告诉解释器、编译器某个变量赋值是针对一个局部变量还是一个成员变量,但出于解释性语言的性能考虑,最好是语义上的的规定。C++用变量必须显示的声明解决了这个问题,但Python没有额外的变量声明语法,如果仅仅是出于上面所说的目的引入类似C++的变量必须显式的声明就显得太得不偿失了。

所以,self.var这种语法就是一个非常优美的解决方案。我们在函数里写上self.var这种语法,解释器就不用费力地在全局范围内进行变量的查找。换句话说,局部变量和成员变量存在于两个不同的命名空间,我们需要告诉Python我们用的是哪个空间。

Python学习群:238757010

为什么Python类成员的调用和声明必须有"this"?的更多相关文章

  1. python 类成员函数

    http://cowboy.1988.blog.163.com/blog/static/75105798201091141521583/ 这篇文章总结的非常好 主要注意的地方是 1,在类内调用成员函数 ...

  2. 转:从pickle看python类成员的动态加载和类的定位

      pickle是Python轻便的对象序列化工具.使用pickle可以方便地把python对象写入文件对象中,或者像soap那样在socket间传送.     按照python的一贯作风,类的成员在 ...

  3. 测试Python类成员的单下划线,双下划线,两头下划线的区别

    首先原谅一个菜鸟叫他“两头下划线”.记得在windows编程中,很多宏定义使用下划线+大写,给人逼格很高的错觉.对于Python下划线的认识,大概是从__dict__这个属性开始的,看__dict__ ...

  4. python - 类成员修饰符

    在java,c#类的成员修饰符包括,公有.私有.程序集可用的.受保护的. 对于python来说,只有两个成员修饰符:公有成员,私有成员 成员修饰符是来修饰谁呢?当然是修饰成员了.那么python类的成 ...

  5. python 类成员知识点学习的一个坑(初学者,大神请绕行)

    先来段小程序class Foo: name = "abc" def __init__(self,age): self.age = age print(Foo.name)Foo.na ...

  6. python 类成员的修饰符

    类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式: 公有成员,在任何地方都能访问 私有成员,只有在类的内部才能方法 私有成员和公有成员的定义不同:私有成员命名时,前两个字 ...

  7. Python类和实例调用

    self指向的是实例对象,作为第一个参数,使用时不需要传入此参数. class Student(object): #定义一个Student类, def __init__(self, name, sco ...

  8. python 面向对象和类成员和异常处理

    python 面向对象 你把自己想象成一个上帝,你要创造一个星球,首先你要把它揉成一个个球,两个直径就能创造一个球 class star: '''名字(name),赤道直径(equatorial di ...

  9. C#的类成员初始化顺序

    C#的类成员的定义和声明如下 using UnityEngine; using System.Collections; public class TestController : ECControll ...

随机推荐

  1. UNIX高级环境编程(6)标准IO函数库 - 流的概念和操作

    标准IO函数库隐藏了buffer大小和分配的细节,使得我们可以不用关心预分配的内存大小是否正确的问题. 虽然这使得这个函数库很容易用,但是如果我们对函数的原理不熟悉的话,也容易遇到很多问题.   1 ...

  2. Oracle数据库运维:要对监听日志文件(listener.log)进行定期清理,如果不定期清理,会遇到下面一些麻烦

    原文链接: http://www.lookdaima.com/WebForms/WebPages/Blanks/Pm/Docs/DocItemDetail.aspx?EmPreviewTypeV=2& ...

  3. Nodejs和npm入门使用

    目录 引子 何为node.js 和 npm 怎么使用node.js和npm 安装node.js & npm npm init 初始化项目(创建node.js模块) Package.json 属 ...

  4. windows server 2016部署服务

          绪论 有时候,如果安装系统数量比较多,而且数量较多,人工使用U盘或者光盘安装,效率较低,通过网络可以批量安装. 还可以做到无人安装. PXE PXE(preboot execute env ...

  5. web应用配置文件详解(web.xml)

    转载链接地址:http://blog.csdn.net/guihaijinfen/article/details/8363839 <?xml version="1.0" en ...

  6. Java基础 之软引用、弱引用、虚引用 ·[转载]

    Java基础 之软引用.弱引用.虚引用 ·[转载] 2011-11-24 14:43:41 Java基础 之软引用.弱引用.虚引用 浏览(509)|评论(1)   交流分类:Java|笔记分类: Ja ...

  7. DevExpress02、RibbonControl

    RibbonControl 常用操作 1.如何代码显示选中的页 ribbonControl1.SelectedPage = ribbonPage2; 2.如何绑定ApplicationMenus和Po ...

  8. #001 HTML快速入门讲解

    整理了下最早开始学习技术的笔记  3W1H学习法? (其他技术同理) What   HTML是什么? When  什么时候使用HTML? Why    为什么使用HTMl? HOW  怎么使用HTML ...

  9. JS传递函数并且调用

    封装的函数: function getDataByJsonP(methName, inData, fn) { // 这里fn可以直接传入函数名字 $.ajax({ url: '', //请求的url地 ...

  10. 图片保持比例,padding的妙用

    要保持图片的比例不变 这一张图片在不同分辨率(1980px, 1364px,移动端400px)下均保持了一定的比例不变. 方法: padding以及margin的上下(margin-top | mar ...