原文地址https://blog.csdn.net/love666666shen/article/details/78189984

Python中的self

在Python中的类Class的代码中,常看到函数中的第一个参数,都是self;

同时Class中的函数里面,访问对应的变量(读取或者写入),以及调用对应的函数时,都是self.valueName,self.function()的形式。

不适用类Class直接编写函数时倒没有注意,一旦编写类,调用其中的函数是老是出现参数或多或少的情况,这时候才回过头来深入看了看self的含义和具体的使用。

Python中self的含义

self,

英文单词意思很明显,表示自己,本身。此处有几种潜在含义:

1.这里的自己,指的是,实例Instance本身。

2.同时, 由于说到“自己”这个词,都是和相对的“其他”而说的。此处的其他,指的是,类Class,和其他变量,比如局部变量,全局变量等。

此处的self,是个对象,Object。是当前类的实例。因此,对应的self.valueName,self.function()中的valueName和function()具体含义如下:

valueName:表示self对象,即实例的变量。与其他的Class的变量,全局的变量,局部的变量,是相对应的。

function:表示是调用的是self对象,即实例的函数。与其他的全局的函数,是相对应的。

Python中为何要有self

如果没有在__init__中初始化对应的实例变量的话,导致后续引用实例变量会出错

如下代码,完整的演示了,如果没有在类Class的最初的__init__函数中,正确的初始化实例变量,则会导致后续没有变量可用,因而出现AttributeError的错误:

#!/usr/bin/python#-*- coding: utf-8 -*-#注:此处全局的变量名,写成name,只是为了演示而用#实际上,好的编程风格,应该写成gName之类的名字,以表示该变量是Global的变量

name="whole global name";

classPerson:

def__init__(self, newPersonName):#self.name = newPersonName;

#1.如果此处不写成self.name

#那么此处的name,只是__init__函数中的局部临时变量name而已

#和全局中的name,没有半毛钱关系

name=newPersonName;#此处的name,只是__init__函数中的局部临时变量name而已

#此处只是为了代码演示,而使用了局部变量name,

#不过需要注意的是,此处很明显,由于接下来的代码也没有利用到此处的局部变量name

#则会导致:此处的name变量,实际上被浪费了,根本没有被使用

defsayYourName(self):#此处由于找不到实例中的name变量,所以会报错:

#AttributeError: Person instance has no attribute 'name'

print'My name is %s'%(self.name);

defselfAndInitDemo():

personInstance=Person("crifan");

personInstance.sayYourName();###############################################################################

if__name__=="__main__":

selfAndInitDemo();

从上述代码可见,由于在类的初始化(实例化)的__init__函数中,没有给self.name设置值,使得实例中,根本没有name这个变量,导致后续再去访问self.name,就会出现AttributeError的错误。

对应的,如果写成self.name就正确了,就是初始化的时候,在实例中新增加并且设置了正确的值newPersionName,所以后续再去通过self.name,就可以访问到当前实例中正确的变量name了。

相应的正确写法的代码如下:

#注:此处全局的变量名,写成name,只是为了演示而用

#实际上,好的编程风格,应该写成gName之类的名字,以表示该变量是Global的变量

name="whole global name";

classPerson:

def__init__(self, newPersionName):#相当于java中的Person类的构造方法

#此处正确的,通过访问self.name的形式,实现了:#1.给实例中,增加了name变量#2.并且给name赋了初值,为newPersonNameself.name=newPersonName;

defsayYourName(self):#此处由于开始正确的初始化了self对象,使得其中有了name变量,所以此处可以正确访问了name值了,可以正确的输出了:#My name is crifanprint'My name is %s'%(self.name);

defselfAndInitDemo():

personInstance=Person("crifan");

personInstance.sayYourName();###############################################################################

if__name__=="__main__":

selfAndInitDemo();

有时候,虽然写的代码,可以运行,但是使用到的变量,由于没有加self,实际上用到的不是实例变量,而是其他的变量。

此类问题,主要和Python中的变量的作用域有关,但在下面例子中,也和是否使用self有关:

#注:此处全局的变量名,写成name,只是为了演示而用

#实际上,好的编程风格,应该写成gName之类的名字,以表示该变量是Global的变量

name="whole global name";

classPerson:

name="class global name"def__init__(self, newPersonName):#self.name = newPersonName;#此处,没有使用self.name#而使得此处的name,实际上仍是局部变量name#虽然此处赋值了,但是后面没有被利用到,属于被浪费了的局部变量name

name=newPersonName;

defsayYourName(self):#此处,之所以没有像之前一样出现:#AttributeError: Person instance has no attribute 'name'#那是因为,虽然当前的实例self中,没有在__init__中初始化对应的name变量,实例self中没有对应的name变量#但是由于实例所对应的类Person,有对应的name变量,所以也是可以正常执行代码的#对应的,此处的self.name,实际上是Person.name

print'My name is %s'%(self.name); #-> class global nameprint'name within class Person is actually the global name: %s'%(name); #-> whole global nameprint"only access Person's name via Person.name=%s"%(Person.name); #-> class global name

defselfAndInitDemo():

personInstance=Person("crifan");

personInstance.sayYourName();print"whole global name is %s"%(name); #-> whole global name

###############################################################################

if__name__=="__main__":

selfAndInitDemo();

可见,此处__init__中,没有给self实例初始化对应的name,而在后面的函数sayYourName中,虽然可以调用到self.name但并没有出现AttributeError错误。

然而,实际上此处的值,不是所期望传入的name,即"crifan",而是类中的name的值,即"class global name"。

self代表类的实例,而非类。

self不必非写成self

self可以不写吗

在Python的解释器内部,当我们调用t.prt()时,实际上Python解释成Test.prt(t),也就是说把self替换成类的实例。

有兴趣的童鞋可以把上面的t.prt()一行改写一下,运行后的实际结果完全相同。

实际上已经部分说明了self在定义时不可以省略,如果非要试一下,那么请看下面:

classTest:

defprt():print(self)

t=Test()

t.prt()

当然,如果我们的定义和调用时均不传类实例是可以的,这就是类方法。

classTest:

defprt():print(__class__)

Test.prt()

运行结果如下

在继承时,传入的是哪个实例,就是那个传入的实例,而不是指定义了self的类的实例。

先看代码

classParent:

defpprt(self):print(self)

classChild(Parent):

defcprt(self):print(self)

c=Child()

c.cprt()

c.pprt()

p=Parent()

p.pprt()

在描述父类中,self指的是描述父类的实例

不太容易理解,先看实例:

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

运行结果如下:

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>

总结

self在定义时需要定义,但是在调用时会自动传入。

self的名字并不是规定死的,但是最好还是按照约定是用self

self总是指调用时的类的实例。

用代码演示如下:

classPerson:

def__init__(self, newPersonName):#在开始初始化新的类Class的示例Instance的时候,给对应的,不同的Instance,设置不同的人名(Person name)self.name=newPersonName;

defsayYourName(self):#不同的Person的示例,调用同样的方法的时候,说出自己的名字,结果都是对应着自己的,各自不同的名字print'My name is %s'%(self.name); #My name is crifan

definitDemo():

persionInstance=Person("crifan");

persionInstance.sayYourName();###############################################################################

if__name__=="__main__":

initDemo();

其中,针对Person这个类,不同的示例,在初始化的时候,传递一个对应的参数,这样不同的Person,就都有了自己的不同的名字了。

这看起来,有点类似于其他语言中,通过传递特定参数去对类进行初始化。

个人理解小结:

首先明确的是self只有在类的方法中才会有,独立的函数或方法是不必带有self的。self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。

self名称不是必须的,在python中self不是关键词,你可以定义成a或b或其它名字都可以,但是约定成俗,不要搞另类,大家会不明白的。

下例中将self改为myname一样没有错误:

classPerson: def __init__(myname,name): myname.name=name defsayhello(myname): print 'My name is:',myname.namep=Person('Bill')printp

self指的是类实例对象本身(注意:不是类本身)。classPerson: def __init__(self,name): self.name=name defsayhello(self): print 'My name is:',self.namep=Person('Bill')printp

在上述例子中,self指向Person的实例p。 为什么不是指向类本身呢,如下例子:classPerson: def __init__(self,name): self.name=name defsayhello(self): print 'My name is:',self.namep=Person('Bill')p1 = Person('Apple')printp

如果self指向类本身,那么当有多个实例对象时,self指向哪一个呢?所以,self代表的是具体的实例化对象,这样当有多个实例化对象时才不至于混淆不知道调用的是哪一个实例的方法或属性。

python中def _init_是什么意思_Python中self和__init__的含义与使用相关推荐

  1. python中def _init_是什么意思_python中def __init__():的含义

    def __init__():的含义 关于__init__()函数,其本身是python的构造方法.如果不清楚这一点,看着ta就会一脸懵逼. 这个函数类似init()初始化方法,来初始化新创建对象的状 ...

  2. python中def _init_是什么意思_python中的__init__(self)是什么意思呢

    __init__(self)这个时类的初始化函数 classObj:def __init__(self):print 1obj= Obj() #这时候__init__这个函数会被调用,self指obj ...

  3. python中def main是什么意思_Python中’__main__’模块的作用

    Python不同于C/C++,程序执行并不需要主程序,如main(),而是文件自上而下的执行. 但很多Python程序中都有 1 if __name__ == '__main__':2 stateme ...

  4. python中def fun 定义函数列表_python函数

    # -*- coding:utf-8 -*- #yys #python 3.7.2 # 1.定义函数.调用函数 # 函数:组织好的.可重复使用的.用户实现单一或者关联功能的代码段. # 函数能够提高应 ...

  5. python之33个关键字详解_Python 中的关键字 with 详解

    在 Python 2.5 中,with关键字被加入.它将常用的 try ... except ... finally ...模式很方便的被复用.看一个最经典的例子: with open('file.t ...

  6. python 函数参数前面两个星号_Python中参数前面一个星号两个星号(*参数,**参数)起什么作用呢?...

    摘要: 下文讲述Python中参数前面一个星号两个星号的功能分享,如下所示: 在Python语言中,我们经常看见参数前面 加上一个星号或两个星号 那么这些写法到底起什么作用呢? 下文将一一道来,如下所 ...

  7. python中的列表是指针吗_Python中的指针——到底指什么(二)

    在 Python中的指针--到底指什么(一) 中,我们知道在Python的一切都是对象,变量其实是指向PyObject对象的名称,对不可变变量进行操作后,名称指向了另一个PyObject. 扣留对象 ...

  8. python的作用域分别有几种_python中作用域与函数嵌套

    知识回顾: 拆解传参. 1.字典传参.使用** 2.列表传参.使用* 实际上我们在定义函数的时候,如果省略了星号,那么在调用函数的时候必须要省略星号,除非我们拆解后的参数个数刚好相等. 视频内容 本节 ...

  9. python中sys模块是什么内容_python中sys模块是做什么用的

    python中的sys是提供了一系列有关python运行环境的变量和函数的模块,如sys.argv函数实现从程序外部向程序传递参数:sys.platform函数用于获取当前系统平台. sys模块提供了 ...

最新文章

  1. [unity3d]水果忍者-界面搭建
  2. 【跃迁之路】【732天】程序员高效学习方法论探索系列(实验阶段489-2019.2.22)...
  3. NET防SQL注入方法
  4. 解决网卡无法自动获取ip的办法
  5. Spark_Sql50题(DataFrame)
  6. 使用Ansible进行硬件引导
  7. 图书馆图书搜索引擎(全球100多图书馆)
  8. 北京理工大学计算机面试题,北京理工大学自主招生面试试题综合素质答案技巧.doc...
  9. Java笔记009-数组、排序、查找、多维数组(二维数组)
  10. 淘宝API接口调用:item_search_img - 按图搜索淘宝商品(拍立淘)
  11. linux下 解压iso 命令行
  12. python123.io同一个号可以同时在不同设备登陆吗-Python 高级 3
  13. 学习HC-SR04超声波测距模块,代码附带卡尔曼滤波
  14. C语言中的void和void*的定义及用法
  15. 电烙铁使用方法,diy套件
  16. Python03(注释、算术运算符、程序执行原理、变量使用)
  17. 13个球一个天平,现知道只有一个和其他的重量不同,问怎样称才能用3次就找到那个球?
  18. 微信小程序 阻止 onshow请求数据
  19. WhiteBox学习
  20. 如何在你的WordPress网站上添加成本计算器

热门文章

  1. 封装时间转换工具类_推荐一款封装各种Util工具类,这款神仙级框架你值得拥有!...
  2. oracle linux telnet,linux如何开启telnet服务
  3. 实心和空心哪个抗弯能力强_空心楼板技术优势及施工工艺
  4. nignx uwsgi 启动多个flask网站
  5. x86_64 ubuntu18.04.4 python3.6.9 安装 cuda8.0 和 cudnn5.1
  6. AI 利用BP算法及Sigmoid函数,研究函数f(x)=2sinx-0.7的逼近问题-实验报告
  7. 多尺度目标检测--Scale-Aware Trident Networks for Object Detection
  8. 人脸检测--Face Detection with End-to-End Integration of a ConvNet and a 3D Model
  9. Latex使用技巧01:改变数学公式字体的颜色
  10. 手把手教你学Kotlin (1): JetBrains的Kotlin Educational Tool下载、安装和 Kotlin Koans的安装和使用