python中home定义是什么_搞清楚Python中self的含义
刚开始学习Python的类写法的时候觉得很是麻烦,为什么定义时需要而调用时又不需要,为什么不能内部简化从而减少我们敲击键盘的次数?你看完这篇文章后就会明白所有的疑问。
self代表类的实例,而非类。
实例来说明
Python
classTest:defprt(self):print(self)print(self.__class__)
t=Test()
t.prt()
执行结果如下
Python
<__main__.Test object at 0x000000000284E080>
从上面的例子中可以很明显的看出,self代表的是类的实例。而self.class则指向类。
self不必非写成self
有很多童鞋是先学习别的语言然后学习Python的,所以总觉得self怪怪的,想写成this,可以吗?
当然可以,还是把上面的代码改写一下。
Python
classTest:defprt(this):print(this)print(this.__class__)
t=Test()
t.prt()
改成this后,运行结果完全一样。
当然,最好还是尊重约定俗成的习惯,使用self。
self可以不写吗
在Python的解释器内部,当我们调用t.prt()时,实际上Python解释成Test.prt(t),也就是说把self替换成类的实例。
有兴趣的童鞋可以把上面的t.prt()一行改写一下,运行后的实际结果完全相同。
实际上已经部分说明了self在定义时不可以省略,如果非要试一下,那么请看下面:
Python
classTest:defprt():print(self)
t=Test()
t.prt()
运行时提醒错误如下:prt在定义时没有参数,但是我们运行时强行传了一个参数。
由于上面解释过了t.prt()等同于Test.prt(t),所以程序提醒我们多传了一个参数t。
Python
Traceback (most recent call last):
File"h.py", line 6, in t.prt()
TypeError: prt() takes 0 positional arguments but1 was given
当然,如果我们的定义和调用时均不传类实例是可以的,这就是类方法。
Python
classTest:defprt():print(__class__)
Test.prt()
运行结果如下
Python
在继承时,传入的是哪个实例,就是那个传入的实例,而不是指定义了self的类的实例。
先看代码
Python
classParent:defpprt(self):print(self)classChild(Parent):defcprt(self):print(self)
c=Child()
c.cprt()
c.pprt()
p=Parent()
p.pprt()
运行结果如下
Python
<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>
解释:
运行c.cprt()时应该没有理解问题,指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt(c),所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,所以沿着继承树往上找,发现在父类Parent中定义了pprt()方法,所以就会成功调用。
在描述符类中,self指的是描述符类的实例
不太容易理解,先看实例:
Python
classDesc:def __get__(self, ins, cls):print('self in Desc: %s' %self )print(self, ins, cls)classTest:
x=Desc()defprt(self):print('self in Test: %s' %self)
t=Test()
t.prt()
t.x
运行结果如下:
Python
self in Test: <__main__.Test object at 0x0000000002A570B8>selfin Desc: <__main__.Desc object at 0x000000000283E208>
<__main__.Desc object at 0x000000000283E208> <__main__.Test object at 0x0000000002A570B8>
大部分童鞋开始有疑问了,为什么在Desc类中定义的self不是应该是调用它的实例t吗?怎么变成了Desc类的实例了呢?
注意:此处需要睁大眼睛看清楚了,这里调用的是t.x,也就是说是Test类的实例t的属性x,由于实例t中并没有定义属性x,所以找到了类属性x,而该属性是描述符属性,为Desc类的实例而已,所以此处并没有顶用Test的任何方法。
那么我们如果直接通过类来调用属性x也可以得到相同的结果。
下面是把t.x改为Test.x运行的结果。
Python
self in Test: <__main__.Test object at 0x00000000022570B8>selfin Desc: <__main__.Desc object at 0x000000000223E208>
<__main__.Desc object at 0x000000000223E208> None
题外话:由于在很多时候描述符类中仍然需要知道调用该描述符的实例是谁,所以在描述符类中存在第二个参数ins,用来表示调用它的类实例,所以t.x时可以看到第三行中的运行结果中第二项为。而采用Test.x进行调用时,由于没有实例,所以返回None。
总结
self在定义时需要定义,但是在调用时会自动传入。
self的名字并不是规定死的,但是最好还是按照约定是用self
self总是指调用时的类的实例。
python中home定义是什么_搞清楚Python中self的含义相关推荐
- python怎么创建txt文件啊_搞定Python项目依赖:requirements.txt文件的创建和使用
Python的强大在于它拥有数量众多的第三方库协助开发,在编写Python项目时,我们经常会使用很多第三方模块.由于不同设备和系统的差异性,导致我们很难分散地控制项目依赖(头铁的同学请绕道),于是re ...
- python中home定义是什么_第48p,什么是函数?,Python中函数的定义
原标题:第48p,什么是函数?,Python中函数的定义 大家好,我是 杨数 Tos ,这是<从 零 基础到大神>系列课程的第 48 篇文章 ,第三阶段的课程 : Python进阶知识:详 ...
- python类方法需要传入cls参数_如何从Python 3.x中的类定义传递参数到元类?
这是如何从类定义向元类传递参数的python 3.x版本?问题,根据请求单独列出,因为答案与python 2.x明显不同. 在python 3.x中,如何将参数传递给元类的__prepare__.__ ...
- python函数中可变参数的传递方式_详解Python函数可变参数定义及其参数传递方式...
Python函数可变参数定义及其参数传递方式详解 python中 函数不定参数的定义形式如下 1. func(*args) 传入的参数为以元组形式存在args中,如: def func(*args): ...
- python采用面向对象编程模式吗_如何理解 Python 中的面向对象编程?
现如今面向对象编程的使用非常广泛,本文我们就来探讨一下Python中的面向对象编程. 作者 | Radek Fabisiak 译者 | 弯月,责编 | 郭芮 以下为译文: Python支持多种类型的编 ...
- python中的符号下划线_详解Python中下划线的使用方法
编程派微信号:codingpy 这篇文章讨论Python中下划线_的使用.跟Python中很多用法类似,下划线 _ 的不同用法绝大部分(不全是)都是一种惯例约定. 单个下划线(_) 主要有三种情况: ...
- python中var是什么变量_一、 Python概述、变量
一. Python概述 1.python是一门面向对象,解释型的脚本语言.语法简洁,编写效率高,但是执行(底层运行)效率低(总的来说解释语言执行效率低于编译语言). 注意:本博客所有的代 ...
- python中什么是可变参数_详解Python的三种可变参数
详解Python的三种可变参数 可变参数 可变参数应该最简单,在C/C++和Java等语言中都有,就是用*号来表示,例如 def testArg(*arg) 你可以传入任意多个元素(包括0)到参数中, ...
- python游戏中调整箭头下落速度_入门 | 三行Python代码,让数据预处理速度提高2到6倍...
原标题:入门 | 三行Python代码,让数据预处理速度提高2到6倍 选自TowardsDataScience 作者:George Seif,机器之心编译 在 Python 中,我们可以找到原生的并行 ...
- java如何给一个链表定义和传值_如何在CUDA中为Transformer编写一个PyTorch自定义层...
如今,深度学习模型处于持续的演进中,它们正变得庞大而复杂.研究者们通常通过组合现有的 TensorFlow 或 PyTorch 操作符来发现新的架构.然而,有时候,我们可能需要通过自定义的操作符来实现 ...
最新文章
- 内存条结构_CPU是电脑里最难坏的硬件,为什么不敢终身质保,而内存条却可以...
- 新中大oracle实列名,新中大财务软件操作流程(完整版)
- 2015-10-15 css3
- linux ll 文件大小单位_该如何改善 Linux 系统性能?
- BlackBerry 应用程序开发者指南 第二卷:高级--第11章 管理通知(Notification)
- 栈和队列:2.队列(Queue)及其C语言实现
- 运行 lighttrack 遇到错误和解决方法
- @程序员,你的编程方式已过时,云开发时代来临!
- dubbo源码之SPI机制源码
- 【蓝桥杯国赛真题24】Scratch货物运输 第十三届蓝桥杯 图形化编程scratch国赛真题和答案讲解
- SpringBoot-DDD领域驱动设计的概念
- 对称加密算法原理简介
- CentOS 6.3安装 flash控件成功案例(其它方法未成功)
- Linux下rsync安装与配置
- 火爆科研圈的三维重建技术:Neural radiance fields (NeRF)
- 【UV打印机】电气之光电传感器
- Hystrix断路器执行原理
- python官网各个版本下载地址
- Chrome浏览器首页被hao123劫持的解决办法
- 战痘实录,又同样烦恼的可以看看(转)
热门文章
- MySQL指令集集合
- 《云计算:原理与范式》一3.2 知识经济时代的来临
- (转)战斗bug技巧全攻略
- IC卡读写器VB.NET源代码
- 用思科2610搭建PSTN拨号网络
- java net 安卓_Java和Android Http连接程序:使用java.net.URL 下载服务器图片到客户端...
- 以rpm包形式升级Linux驱动
- linux下实现在程序运行时的函数替换(热补丁)
- Ceph 撸源码系列(二):Ceph源代码里的那些锁 std::mutex(2 of 3)
- SFML图形库学习:环境部署