参考原文链接:https://blog.csdn.net/xrinosvip/article/details/89647884

在Python类中规定,函数的第一个参数是实例对象本身,并且约定俗成,把其名字写为self。其作用相当于java中的this,表示当前类的对象,可以调用当前类中的属性和方法

class是面向对象的设计思想,instance(也即是 object,对象)是根据 class 创建的

一个类(class)应该包含 数据操作数据的方法,通俗来讲就是 属性 和 函数(即调用方法)

类 class 中为啥用使用 self ?

在类的代码(函数)中,需要访问当前的实例中的变量和函数,即,访问Instance中的:

对应的变量(property):Instance.ProperyNam,去读取之前的值和写入新的值

调用对应函数(function):Instance.function(),即执行对应的动作

-> 而需要访问实例的变量和调用实例的函数,当然需要对应的实例Instance对象本身

-> 而Python中就规定好了,函数的第一个参数,就必须是实例对象本身,并且建议,约定俗成,把其名字写为self

-> 所以,我们需要self

首先,在Python中类的定义:

在python中,类是通过关键字 class 定义的:class 后面紧跟 类名,即 Person,类名通常大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用 object 类,这是所有类最终都会继承的类

class Person(object):pass

将 Person类实例化,创建实例化是通过 类名() 实现的如 Person()

class Person(object):pass
student = Person()    # 创建类的实例化
print(student)
print(Person)


可以看到,变量 student指向的就是一个 Person的 object,后面的 0x0000026EE434D8D0 是内存地址,每个 object 的地址都不一样,而 Person 本身则是一个 类

实例变量绑定属性比如:为 student 绑定 name 和 score 属性

class Person(object):pass
student = Person()
# print(student)
# print(Person)
student.name = "Gavin"     # 为实例变量 student 绑定 name 属性   类似于 赋值 操作
student.score = 100        # 为 其绑定  score 属性
print(student.name)
print(student.score)


上述的方法虽然可以为类的实例变量绑定属性,但是不够方便和elegant , 由于类可以起到模板的作用,故在创建实例的时候,可以将我们认为必须绑定 属性 强制填写进去,在 python中,是通过 类中的一个方法,即def __init__(self) 方法,在创建实例变量的时候,就把 name 和 score 等属性绑上去

 class Person(object):def __init__(self,name,score):self.name = nameself.score = scorestudent = Person('Gavin',100)#传入 __init__ 方法中需要的 参数student = Person()# 此处应该有参数传入,却没有传 这样会报错
print(student.name)
print(student.score)


注意:

  • 1、init 方法的第一个参数永远是 self ,表示创建的实例本身,因此,在 __init__ 方法的内部,就可以把各种属性绑定到 self,如def __init__(self,name,score):
  • 2、使用了 init 方法,在创建实例的时候就不能传入 空的参数了,必须传入与 __init__ 方法匹配的参数,但是 self不需要传,python解释器会自己把实例变量传进去

在类中定义多个函数相互调用

 class Person(object):def __init__(self,x,y):self.x = xself.y = ydef add(self):sum = self.x + self.yreturn sumdef square(self):squr = pow(self.x,2)+pow(self.y,2)return squrdef add_square(self):c = self.add()+self.square()return cstudent = Person(3,4)
print(student.add())
print(student.square())
print('--------- 我是可爱的分割线-----------')
print(student.add_square())

通过上述的例子可以看出,与普通的函数相比,在类中定义的函数只有两点点不同:

  • 1、第一个参数永远是 self ,并且调用时不用传递该参数
  • 2、在类中函数相互调用要加 self ,如上例中:c = self.add()+self.square()`, 不加 self ,会报错:
    函数未定义,看下图

class Person(object):def __init__(self,x,y):self.x = xself.y = ydef add(self,z=16):         # 设置 默认变量 z =16,这只是个普通的局部变量,非实例变量,实例变量需要 self.z = z,这样定义sum = self.x + self.y + zreturn sumdef square(self):squr = pow(self.x,2)+pow(self.y,2)return squrdef add_square(self,z):        #  调用时传入变量,这也是个普通的局部变量,非实例变量 c = self.add()+self.square() + zreturn cstudent = Person(3,4)
print(student.add())
print(student.square())
print('--------- 我是可爱的分割线-----------')
print(student.add_square(16))# 设置默认变量 z =16,这只是个普通的局部变量,#非实例变量,实例变量需要 self.z = z,这样定义


self简单的说就是把 class 中 定义的 变量和函数 变成 实例变量和实例函数,作为类 class 的成员,使得成员间能互相调用,而不需要从外部调用 数据(即变量)和 方法(即 函数),以实现数据的封装,以上面的 Person 类为例:创建实例的时候需要给出实例变量 x,y, 调用函数时给出非实例变量 z ,调用很容易,却不知道内部实现的细节

类是创建实例的模板,而实例是具体的对象,各个实例拥有的数据都相互独立、互不影响;方法是与实例绑定的函数,和普通的函数不同,方法可以直接访问实例的数据

其实 self 中存储的是 实例变量 和 实例函数 的属性,可以理解为一个字典( dict ),如:{‘name’:‘zhang’,‘age’:‘18’}就是这些。

注意:只有数据属性,并没有创建新的类的方法。 类----->通过实例化生成----对象---->对象只是一串类似于字典的数据,没有把类的里的方法复制给你,python没有new这个方法!)

class Person(object):def __init__(self,x,y):self.x = xself.y = ydef add(self,z=16):     # 设置 z 为实例变量,即 self.z = z, z 是 class 的一个成员了,而非普通局部变量self.z = zsum = self.x + self.y + z  # z虽然已被实例化,但是依然可以当作 普通变量来用return sumdef square(self):squr = pow(self.x,2)+pow(self.y,2)return squrdef add_square(self):        c = self.add()+self.square() + self.z  # 调用实例变量 z return cstudent = Person(3,4)
print(student.add())
print(student.square())
print('--------- 我是可爱的分割线-----------')
print(student.add_square())
print(student.z)          # 函数add 中的 z 被实例化以后,就可以利用实例化的方法访问它

z 本来是 add() 函数的默认形参,通过将其实例化,就可以在其他函数体内调用
实例变量 z 被实例化以后,就可以利用实例化的方法访问它

self 到底是什么?

class Box(object):def __init__(self, boxname, size, color):self.boxname = boxnameself.size = sizeself.color = color  # self就是用于存储对象属性的集合,就算没有属性self也是必备的def open(self, myself):print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))print('-->用类自己的self,打开那个%s,%s的%s' % (self.color, self.size, self.boxname))def close(self):print('-->关闭%s,谢谢' % self.boxname)b = Box('魔盒', '14m', '红色')
b.close()
b.open(b)  # 本来就会自动传一个self,现在传入b,就会让open多得到一个实例对象本身,print看看是什么。
print(b.__dict__)  # 这里返回的就是self本身,self存储属性,没有动作。`

print(b.__dict__) # 这里返回的就是self本身,self存储属性,没有动作。

self代表类的实例,而非类;self 就是 对象/实例 属性集合

Box 是个类-----》self 实例化------》 b对象/ 实例
class 抽象体------》实例化------》对象/实例,
含有属性:{'boxname':'魔盒', ‘size’:‘14m’, 'color':'red'},即 self

描述了 self 就是得到了 对象,所以 self 内的键值可以直接使用

class Box(object):def myInit(mySelf, boxname, size, color):print(mySelf.__dict__)#显示为{}空字典mySelf.boxname = boxnamemySelf.__dict__['aa'] = 'w'#甚至可以像字典一样操作mySelf.size = sizemySelf.color = color  # 自己写一个初始化函数,一样奏效,甚至不用self命名。其它函数当中用标准selfreturn mySelf  # 返回给实例化过程一个对象!神奇!并且含有对象属性/字典# def __init__(self, boxname, size, color):#     self.boxname = boxname#     self.size = size#     self.color = color  #注释掉原来标准的初始化def open(self, myself):print(self)print('-->用自己的myself,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))print('-->用类自己的self,打开那个%s,%s的%s' % (myself.color, myself.size, myself.boxname))def close(self):print('-->关闭%s,谢谢' % self.boxname)# 经过改造,运行结果和标准初始化没区别b = Box().myInit('魔盒', '14m', '红色')
# b = Box('魔盒', '14m', '红色')#注释掉原来标准的初始化方法
b.close()
b.open(b)  # 本来就会自动传一个self,现在传入b,就会让open多得到一个实例对象本身,print看看是什么。
print(b.__dict__)  # 这里返回的就是self本身,self存储属性,没有动作。


自定义的myInit()和__init__()初始化的差别:

  • b = Box().myInit(‘魔盒’, ‘14m’, ‘红色’)

  • b = Box(‘魔盒’, ‘14m’, ‘红色’)#原来的初始化方法

注意

  • mySelf.dict[‘aa’] = ‘w’ #甚至可以像字典一样操作
  • 在 b.dict 的结果中显示为:‘aa’:‘w’

故可以把self 理解成存储实例化对象属性字典(dict), self 存储属性,而没有动作执行,self总是指调用时的类的实例

python 中一些特殊的实例变量:

  • 1、私有变量(private),只有内部可以访问,外部不能访问,私有变量是在名称前以两个下划线开头,如:__name,其实私有变量也不是完全不能被外部访问,不能直接访问是因为python解释器对外把 __name 变量改成了 _类名__name,所仍然可以通过 _类名__name 来访问 __name .
  • 2、在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名
  • 3、以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问

python的self相关推荐

  1. Github配置(git+vscode+python+jupyter)

    ①下载git 打开 git bash 工具的用户名和密码存储 $ git config --global user.name "Your Name" $ git config -- ...

  2. 【实验楼】python简明教程

    ①终端输入python进入 欣赏完自己的杰作后,按 Ctrl + D 输入一个 EOF 字符来退出解释器,你也可以键入 exit() 来退出解释器. ②vim键盘快捷功能分布 ③这里需要注意如果程序中 ...

  3. 【Kaggle Learn】Python 5-8

    五. Booleans and Conditionals Using booleans for branching logic x = True print(x) print(type(x))''' ...

  4. 【Kaggle Learn】Python 1-4

    [Kaggle Learn]Python https://www.kaggle.com/learn/python 一. Hello, Python A quick introduction to Py ...

  5. 使用python愉快地做高数线代题目~

    今天接触到了python,发现真是极易上手啊!对比c语言是什么鬼东西= = 诶,等下,看完教学文章发现TA在下面写了这句话 如果做了前面的内容你可能已被吸引了,觉得c语言真的是废材! 不...不是的. ...

  6. python 位运算与等号_Python 运算符

    和大多数语言一样,Python也有很多运算符,并且运算符跟其他语言的运算符大同小异接下来一一介绍: 算术运算符: 运算符描述实例 +加 - 两个对象相加a+b的输出结果是30 -减 - 得到复数或者一 ...

  7. python减小内存占用_如何将Python内存占用缩小20倍?

    当程序执行过程中RAM中有大量对象处于活动状态时,可能会出现内存问题,特别是在对可用内存总量有限制的情况下. 下面概述了一些减小对象大小的方法,这些方法可以显著减少纯Python程序所需的RAM数量. ...

  8. python中排序英文单词怎么写_Python实现对文件进行单词划分并去重排序操作示例...

    本文实例讲述了Python实现对文件进行单词划分并去重排序操作.,具体如下: 文件名:test1.txt 文件内容: But soft what light through yonder window ...

  9. python程序如何执行死刑图片_如何判断对象已死

    已死的对象就是不可能被任何途径使用的对象,有以下几种方法判断一个对象是否已经死了: 引用计数 给对象添加一个引用计数器,每当有一个地方引用他,计算器就加 1:当引用失效时,计数器减 1:任何时刻计数器 ...

  10. Python gRPC 安装

    1. 安装依赖库 sudo pip3 install grpcio sudo pip3 install protobuf sudo pip3 install grpcio_tools 2. 生成对应文 ...

最新文章

  1. python 学习之 PythonAdvance2
  2. 图像标记工具Labelme和LabelImg
  3. Leetcode-探索 | 存在重复
  4. 18岁学计算机专业好不好,我18岁,学计算机编程,请问有没有什么书或者方法可以提高记忆力的?...
  5. r型聚类典型指标_六种GAN评估指标的综合评估实验,迈向定量评估GAN的重要一步...
  6. 邀您参加 | K8S云原生技术开放日-北京站
  7. [二叉树] 二叉树的最近公共祖先--leetcode236
  8. Jenkins 详细安装、构建部署 使用教程
  9. bzoj2423[HAOI2010]最长公共子序列
  10. extjs combobox分页加载数据不显示
  11. Hadoop 安装教程
  12. VISSIM二次开发(Python)大作业总结2
  13. PDPS教程之工艺仿真必备软件
  14. springboot + vue 搭建使用maven+ant构建
  15. 用python 制作视频播放器
  16. 从源码分析Android的Glide库的图片加载流程及特点
  17. 中国烟草和水烟行业市场供需与战略研究报告
  18. BD新标签页-最值得安装的浏览器插件
  19. 几个工程符号 T,G,M,K,f,p,n
  20. 0x80073712_win10系统更新提示错误代码“0x80073712”的解决方法

热门文章

  1. 重磅!阿里巴巴和全球最大奢侈品电商YNAP成立合资公司
  2. Solr及Spring-Data-Solr入门学习
  3. 花旗看好互联网板块 力荐Facebook等5支网络股
  4. django 1.8 官方文档翻译:8-5 加密签名
  5. HTML/CSS/动画
  6. Delphi的“动态窗体”技术实际应用[网络摘抄]
  7. 中小型企业部分拓朴结构配置方法
  8. 北京.net俱乐部博客园小组成立了
  9. 什么是WebService??
  10. C语言基于GTK+Libvlc实现的简易视频播放器(二)