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. SQL脚本运行

    $v=New-Object -ComObject wscript.shell#也可以使用反单引号(`)字符来强制PowerShell将单引号或双引号解释为文本,0不显示命令提示符窗口$v.run(&q ...

  2. SQL语言DDL DML DCL TCL四种语言

    1.DDL(Data Definition Language)数据库定义语言:DDL使我们有能力创建或删 除表格.可以定义索引(键),规定表之间的链接,以及施加表间的 约束. • 常见DDL 语句: ...

  3. 一份非常完整的 MySQL 规范

    源自:https://www.cnblogs.com/huchong/p/10219318.html 一.数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割. 所有数据库对象名称禁止使用 ...

  4. zabbix日常监控Apache2.4

    Apache的安装请参考https://www.cnblogs.com/huangyanqi/p/9168637.html 1.修改配置 [root@apache ~]# httpd -v Serve ...

  5. (1)I/O流 (2)线程

    1.I/O流1.1 ObjectOutputStream类(重点)(1)基本概念 java.io.ObjectOutputStream类主要用于将Java对象整体写入到输出流中. 只能将支持 java ...

  6. 【4】python函数基础

    ---恢复内容开始--- 案例1:时间下一秒程序 #__author:"吉勇佳" #date: 2018/10/14 0014 #function: timestr=input(& ...

  7. TeamViewer app案例分析

    产品 产品名 TeamViewer远程app 选择原因 远程连接软件是不时之需,当有时私人电脑没有在身边而又需要操作电脑时,远程控制TeamViewer这个软件能帮我们大忙. 调研与评测 1.第一次上 ...

  8. 项目属性的target platform和target platform version到底是什么(vs2015开发windows驱动小记)

    根据官方对属性页的介绍(General Property Page (Project))可了解: target platform是build后的结果会跑在哪个平台,例如windows,android, ...

  9. Maven实战(八)pom.xml简介

    目录 pom作为项目对象模型.通过xml表示maven项目,使用pom.xml来实现.主要描述了项目:包括配置文件.开发者需要遵循的规则.缺陷管理系统.组织和licenses.项目的url.项目的依赖 ...

  10. Python实现向s3共享存储上传和下载文件

    #!/usr/bin/env python #-*- encoding: utf8 -*- import boto import boto.s3.connection from boto.s3.key ...