第7.5节 揭开Python类中self的面纱
在上节已经引入介绍了类定义,并简单介绍了类变量、实例变量、类方法和实例方法,后面章节还会进一步详细介绍相关的内容。本节要介绍的self是与类变量、实例变量、类方法和实例方法具体定义实现强相关的。
一、什么是self?
在Python中self实际上是指向类声明的实例对象自身,如果要在实例方法中访问实例变量,必须在变量前加“self.”。显然,self很有用,甚至必不可少。如果没有它,所有的方法都无法访问对象本身的属性。
二、 self的使用
1. 定义实例方法时,self必须是方法的第一个参数,这种类的方法定义中传递第一个参数为self的方法即使实例方法;
2. self代表类的实例,而非类,而self.__class__则指向类, self在定义时不可以省略;
3. 在实例化方法调用时,程序不用将调用方的实例作为参数放到调用方法的实参里,而是由Python自动进行处理,自动将实例对象传递给实例方法。以上节的Duck类作为例子,其三个方法定义时都有self作为参数,但在实例对象调用swim的代码中却无参数。;
4. 实例方法访问实例变量时,必须通过self访问,否则赋值语句会被认为是给方法的局部变量赋值,非赋值语句会报变量没有定义;
5. 类的实例变量可以通过“实例名.属性”的在实例方法和类外面直接访问。
1) 有个例外,变量名如果是两个下划线开头,则无法这样直接访问。
2) 两个下划线开头的变量,可以通过变量名前加一个下划线+和类名的方式访问。例如如果在Duck类内定义了一个实例变量:”__weight”,实际访问时可以通过”实例名._Duck__weight”的变量名访问。但这种方式不是Python推荐的,老猿也不推荐;
3) 这种加两个下划线的变量类似于c++的私有变量,其访问应该通过实例方法访问,否则对于未知类实现方式的实例直接访问可能引发未知的错误;
6. 如果类的方法中没有self参数,在类的方法定义和调用时均不传类实例是可以的,这样的方法就是类方法和静态方法;
7. “self”这个名字并不是Python强制的名字,只是一种约定俗成,实际上你完全可以起个别的任意名字,如“this”、“me”、“aaa”等,实际上不同实例方法中这个名字都可以不一致,如在构造函数中叫“self1”,在析构函数中叫“self2”,在其他实例方法叫不同的任意名称都可以,但是Python都会作为对象自身处理,并能正确访问,但为了大家方便理解,还是建议大家叫self。使用一个标准的名称有很多优点——你的程序读者可以迅速识别它,如果使用self的话,还有些IDE(集成开发环境)也可以帮助你。
最后有个问题,Python中实例方法第一个参数是“self”,但它又是可以任意命名的,那怎么知道第一个参数是不是实例方法要的self呢?或者说怎么知道这个方法是不是实例方法呢?大家想一想,答案将在后面章节揭晓。
本节介绍了Python中类中神秘的self,有关内容涉及面较广,但实际上理解之后也就比较简单。
老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
欢迎大家批评指正,谢谢大家关注!
第7.5节 揭开Python类中self的面纱的更多相关文章
- 第8.34节 《Python类中常用的特殊变量和方法》总结
本章介绍了Python类中常用的特殊变量和方法,这些特殊变量和方法都有特殊的用途,是Python强大功能的基石之一,许多功能非常有Python特色.由于Python中一切皆对象,理解这些特殊变量和方法 ...
- 第8.26节 重写Python类中的__getattribute__方法实现实例属性访问捕获
一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...
- 第7.14节 Python类中的实例方法详析
第7.14节 Python类中的实例方法详析 一. 实例方法的定义 在本章前面章节已经介绍了类的实例方法,实例方法的定义有三种方式: 1. 类体中定义实例方法 第一种方式很简单,就是在类体 ...
- 第8.12节 Python类中使用__dict__定义实例变量和方法
上节介绍了使用实例的__dict__查看实例的自定义属性,其实还可以直接使用__dict__定义实例变量和实例方法. 一. 使用__dict__定义实例变量 语法: 对象名. dict[属性名] = ...
- 第8章 Python类中常用的特殊变量和方法目录
第8章 Python类中常用的特殊变量和方法 第8.1节 Python类的构造方法__init__深入剖析:语法释义 第8.2节 Python类的__init__方法深入剖析:构造方法案例详解 第8. ...
- 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法
第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一. 案例说明 本节定义了类Sta ...
- 第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析
第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析 静态方法也是通过类定义的一种方法,一般将不需要访问类属性但是类需要具有的一些能力可以静态方法提供. 一 ...
- 第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑
上节<第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解>通过案例详细分析了两个方法的执行顺序,不知大家是否注意到了,在上述 ...
- Python类中super()和__init__()的关系
Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...
随机推荐
- npm的命令参数 --save-dev和 --save两者有什么区别?
我们在安装npm包的时候经常会遇到 --save-dev 和 --save 这两个命令参数,两个命令都是往package.json文件里写入信息,两者有什么区别呢? 1. --save 会把依赖包名称 ...
- “”.length()与“”.split(",").length
public class test { public static void main(String[] args){ String str = ""; System.out.pr ...
- binary hacks读数笔记(ld 链接讲解 二)
这块将介绍一下ld链接命令的具体使用.ld的作用:ld是GNU binutils工具集中的一个,是众多Linkers(链接器)的一种.完成的功能自然也就是链接器的基本功能:把各种目标文件和库文件链接起 ...
- spring的原理
一.pring的原理 1.1 IOC控制反转 ==> 扫描机制通过代理方式动态创建对象 扫描注解,通过反射获取类路径,动态创建对应类的对象,放置在对象池中(多线程做法,防止短时间内创建对象过多, ...
- 【Redis】利用 Redis 实现分布式锁
技术背景 首先我们需要先来了解下什么是分布式锁,以及为什么需要分布式锁. 对于这个问题,我们可以简单将锁分为两种--内存级锁以及分布式锁,内存级锁即我们在 Java 中的 synchronized 关 ...
- 说说基于网络的五种IO模型
# django不是一个异步框架 # tornado是异步的web框架 # 处理每秒大量的请求 # 个人理解的IO:就是应用层与内核驱动层的交互,这个过程无论从应用层到内核中,还是驱动层等待硬件层的数 ...
- C#高级编程之反射
反射的定义 MSDN定义:反射提供描述程序集.模块和类型的对象(Type类型). 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性. 如 ...
- Spring MVC——项目的开发流程
创建项目(IDEA下) 打开IDEA,我们开始创建一个简单的Spring MVC项目,流程如下: 这里要注意一下,我们是基于Maven开发项目,当然是要配置Maven环境的,如果大家之前从来没有配置过 ...
- 死磕以太坊源码分析之p2p节点发现
死磕以太坊源码分析之p2p节点发现 在阅读节点发现源码之前必须要理解kadmilia算法,可以参考:KAD算法详解. 节点发现概述 节点发现,使本地节点得知其他节点的信息,进而加入到p2p网络中. 以 ...
- .Net 开源项目 FreeRedis 实现思路之 - Redis 6.0 客户端缓存技术
写在开头 FreeRedis 是一款继 CSRedisCore 之后重写的 .NET redis 客户端开源组件,以 MIT 协议开源托管于 github,目前支持 .NET 5..NETCore 2 ...