Python类中的__init__() 和 self 的解析

news2024/9/27 7:21:52

1、Python中self的含义

self,英文单词意思很明显,表示自己,本身。

此处有几种潜在含义:

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

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

此处的self,是个对象(Object),是当前类的实例。

因此,对应的self.valueName 和 self.function()中的valueName:表示self对象,即实例的变量。与其他的,Class的变量,全局的变量,局部的变量,是相对应的。

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

2、Python中为何要有self

那就是:

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

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

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

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

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

-> 所以,我们需要self(需要用到self)

而如果没有用到self,即代码中,去掉self后,那种写法所使用到的变量,实际上不是你所希望的,不是真正的实例中的变量和函数,而是的访问到了其他部分的变量和函数了。甚至会由于没有合适的初始化实例变量,而导致后续无法访问的错误。

下面,就通过代码,来演示,如果去掉self,或者没有合理的使用self,会出现哪些错误。

3、首先来看一下__init__()和self对象

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author: antcolonies

class Person(object):

    def __init__(self, name, lang, website):

        self.name = name

        self.lang = lang

        self.website = website

        print('self: 'self)

        print('type of self: 'type(self))

'''

未实例化时,运行程序,构造方法没有运行

'''

= Person('Tim''English''www.universal.com')   

'''实例化后运行的结果

self:  <__main__.Person object at 0x00000000021EAF98>

type of self:  <class '__main__.Person'>

'''

可以看出self为实例变量p,是一个Person类型的对象。

1

2

3

4

5

6

7

8

9

10

11

class Dog(object):       

    def __init__(self,name,dog_type):

        self.name = name

        self.type = dog_type

   

    def sayhi(self):

        print("hello,I am a dog, my name is ",self.name)

   

   

= Dog('LiChuang',"京巴")            # 实例化

d.sayhi()

以下是d = Dog('LiChuang',"京巴")实例化的示意图:

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author: antcolonies

name = 'whole global name'

'''

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

实际上,好的编程风格,应该写成gName之类的名字,

以表示该变量是Global的变量

'''

class Person(object):

    def __init__(self, newPersonName):

        # self.name = newPersonName

        '''

        如果此处不写成self.name

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

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

        '''

        name = newPersonName

        '''

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

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

        则就导致了,此处的name变量,实际上被浪费了,根本没有利用到

        '''

    def sayYourName(self):

        '''

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

        AttributeError: Person instance has no attribute 'name'

        '''

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

def selfAndInitDemo():

    personInstance = Person('Tim')

    personInstance.sayYourName()

if __name__ == '__main__':

    selfAndInitDemo()

'''  未使用self.name时抛异常

Traceback (most recent call last):

  File "E:/python14_workspace/s14/day06/test_1.py", line 18, in <module>

    selfAndInitDemo()

  File "E:/python14_workspace/s14/day06/test_1.py", line 15, in selfAndInitDemo

    personInstance.sayYourName()

  File "E:/python14_workspace/s14/day06/test_1.py", line 11, in sayYourName

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

AttributeError: 'Person' object has no attribute 'name'

'''

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author: antcolonies

name = 'whole global name'

'''

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

实际上,好的编程风格,应该写成gName之类的名字,

以表示该变量是Global的变量

'''

class Person(object):

    def __init__(self, newPersonName):

        self.name = newPersonName

        '''

        此处正确的,通过访问self.name的形式,实现了:

            1.给实例中,增加了name变量

            2.并且给name赋了初值,为newPersionName

        '''

    def sayYourName(self):

        '''

        此处由于开始正确的初始化了self对象,使得其中有了name变量,

        所以此处可以正确访问了name值了

        '''

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

def selfAndInitDemo():

    personInstance = Person('Tim')

    personInstance.sayYourName()

if __name__ == '__main__':

    selfAndInitDemo()

'''My name is Tim'''

5、在函数中,使用对应的变量,虽然代码是可以运行的,但是实际上却是使用的,不是实例中的变量

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author: antcolonies

name = 'whole global name'

'''

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

实际上,好的编程风格,应该写成gName之类的名字,

以表示该变量是Global的变量

'''

class Person(object):

    name = 'class global name'

    def __init__(self, newPersonName):

        # self.name = newPersonName

        '''

        此处,没有使用self.name

        而使得此处的name,实际上仍是局部变量name

        虽然此处赋值了,但是后面没有被利用到,属于被浪费了的局部变量name

        '''

        name = newPersonName

    def sayYourName(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)

        print('Name within class Person is actually the global name: %s' %name)

        print("Only access Person's name via Person.name = %s" %(Person.name))

def selfAndInitDemo():

    personInstance = Person('Tim')

    personInstance.sayYourName()

    print('whole global name is %s' %name)

if __name__ == '__main__':

    selfAndInitDemo()

'''

My name is class global name

Name within class Person is actually the global name: whole global name

Only access Person's name via Person.name = class global name

whole global name is whole global name

'''

其中,可见,此处开始__init__中,没有给self实例初始化对应的name,

而后面的函数sayYourName中,虽然可以调用到self.name而没有出现AttributeError错误,

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/127142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《计算机网络》——第七章知识点

防火墙:特殊编程的路由器&#xff0c;实施访问控制策略。分为网络级防火墙(防止网络出现非法入侵)和应用级防火墙(进行应用的访问控制)。 本次文章详细PDF请点击以下链接查看&#xff1a; https://download.csdn.net/download/qq_53142796/87353770https://download.csdn.n…

市场回暖进行时,实体店商户们千万不要做这三件事!

随着防控措施的进一步优化&#xff0c;市场环境逐渐复苏&#xff0c;许多商户都趁着这段时间开始着手做准备&#xff0c;想要趁年前赚到消费回暖的第一波红利。 但是方向一旦错了&#xff0c;不管付出的努力有多少&#xff0c;最终也只能和想要的结果背道而驰&#xff1b;为了避…

图文结合带你搞懂MySQL日志之Slow Query Log(慢查询日志)

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。作者&#xff1a;KAiTO文章来源&#xff1a;GreatSQL社区原创 什么是慢查询日志 MySQL 的慢查询日志&#xff0c;用来记录在 M…

ORB-SLAM2 --- Tracking::Track 追踪线程解析

1.函数作用 ORB-SLAM2的三大线程之一---跟踪线程&#xff0c;负责估计运动信息、跟踪局部地图。 追踪线程的主要工作原理就是我们从数据集中读入一帧帧&#xff0c;刚开始的时候跟踪线程没有进行初始化&#xff08;没有初始化不知道世界坐标系的原点和相机的位姿&#xff09;&a…

做开发的朋友说软件测试是个人都能学,我当面怒怼

那就分析一下测试工程师需要会哪些技能&#xff1a; 01 软件测试理论 作为一个软件测试人员&#xff0c;总不能不知道软件测试本身的东西吧。 你总要知道软件测试是什么&#xff1f;什么是测试用例&#xff1f;什么是缺陷&#xff1f;软件测试有些什么特点&#xff1f;这些…

OpenHarmony#深入浅出学习eTs#(八)“猜大小”小游戏

本项目Gitee仓地址&#xff1a;[深入浅出eTs学习: 带大家深入浅出学习eTs (gitee.com)]( 上一章节提到的模拟器存在的BUG问题&#xff0c;目前没有办法直接改善&#xff0c;本来打算直接使用鸿蒙远程设备来实现&#xff0c;但是发现支持API8的设备都被抢光了&#xff08;包括模…

如何使用谷歌地图和LightningChart创建地理空间地图图表?

LightningChart JS 是一款高性能的 JavaScript 图表工具&#xff0c;专注于性能密集型、实时可视化图表解决方案。 LightningChart .JS | 下载试用&#xff08;qun&#xff1a;740060302&#xff09;https://www.evget.com/product/4189/download Google Static Maps API 是一…

前端基础(二)_JavaScript变量、JavaScript标识符、JavaScript获取元素、JavaScript的鼠标事件

一、JavaScript变量 变量是存储数据的容器&#xff0c;例x10&#xff0c;则x中存储的值为10。 语法&#xff1a;var 变量名 值。 1.1、变量的声明 先声明后赋值 var x; // 声明变量x alert(x); // undefined 所有声明了但是没有赋值的变量&#xff0c;结果都为undefined X…

单商户商城系统功能拆解55—后台设置

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

水文监测系统 水文遥测终端机 遥测终端机-助力母亲河平稳度汛

平升电子水文监测系统/水文遥测终端机/遥测终端机实现对江河流域水位、降水量、流量、流速、水质、闸门开启度、墒情等数据的实时采集、报送和处理。为防汛抗旱减灾提供科学依据和有效信息共享&#xff0c;保障人民群众生命财产安全&#xff0c;满足水利和经济社会发展对水文服…

虚拟化平台安装并升级显卡驱动

前言 在虚拟化平台上&#xff0c;虚拟化要使用vGPU&#xff0c;需要同时在主机和虚拟机上安装显卡驱动&#xff0c;主机和虚拟机的显卡驱动需要保守一致。安装驱动时先安装主机驱动&#xff0c;再安装虚拟机驱动。 驱动下载 可以从显卡官网许可中心下载对应的虚拟化驱动&…

一篇文章教小白学会搭建 vite + ts + vue3 项目,手把手教程,不会算我输

目录 一、基础环境和工具 1. 使用 pnpm 代替 npm 2. 使用 pinia 代替 vuex 3. 使用 windicss 4. 使用 vscode 5. 使用 sourcetree 6. 了解 vite ts vue 二、项目搭建 1. 流程图 2. 初始化项目 2.1 使用命令初始化项目 2.2 项目结构 3. 使用 git 3.1 创建本地的…

【JavaSE成神之路】数组思考题讲解

哈喽&#xff0c;我是兔哥呀&#xff0c;今天就让我们继续这个JavaSE成神之路&#xff01; 这一节啊&#xff0c;咱们要学习的内容是数组的思考题讲解&#xff0c;也就是上一节我留下的两个小作业。 数组是非常重要的知识点&#xff0c;也是我们后续学习各种数据结构的基础&am…

【MMC子系统】 一、MMC/SD/SDIO介绍

个人主页&#xff1a;董哥聊技术我是董哥&#xff0c;嵌入式领域新星创作者创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01;文章目录1、前言2、MMC/SD/SDIO介绍3、总线接口4、参考文章1、前言 该节学习Linux Kernel的MMC子系统&#xff…

JVM学习笔记(3)—— 运行时数据区—— 程序计数器、虚拟机栈、本地方法栈

程序计数器、虚拟机栈、本地方法栈都是线程私有的&#xff0c;jvm中每个线程都有一份 一、程序计数器 JVM中的程序计数器是一个与PC寄存器功能类似的逻辑结构&#xff0c;用于记录当前线程要执行的下一条jvm指令的地址&#xff0c;解释器读取到对应的jvm指令后将其翻译成机器指…

解决ubuntu(Linux)桌面/应用不插电掉帧问题

解决ubuntu(Linux)桌面/应用不插电掉帧问题 笔记本安装的ubuntu的gnome桌面&#xff0c;插电状态下触摸板动画丝滑&#xff0c;翻看浏览器文章的时候也不会有延迟掉帧的情况&#xff0c;但是离开了充电器&#xff0c;电池供电就会掉帧。 思路&#xff1a;在插电模式下&#x…

Spring Boot三种跨域解决方案与Spring Security跨域解决方案

跨域解决方案1、什么是跨域2、Spring Boot跨域解决方案1、服务端代码2、前端页面3、运行服务3、Spring Security跨域解决方案1、什么是跨域 什么是跨域&#xff0c;首先可以参考我之前写的这篇文章&#xff1a;JavaWeb跨域问题及解决方案 &#xff0c;另外我下面会做补充。 很…

unreal中actor的property replicate简单小节

首先参考的网址是官网中的&#xff1a; https://docs.unrealengine.com/5.1/en-US/multiplayer-programming-quick-start-for-unreal-engine/ unreal引擎的版本是5.1 还原的过程相对比较简单&#xff0c;主要的精力花在了编译报错和调试的过程。 属性复制的流程如下&#xff…

尚医通-MongDB简介-安装-概念-操作(十六)

目录 &#xff08;1&#xff09;MongDB-简介和安装 &#xff08;2&#xff09;MongDB-概念和操作 &#xff08;1&#xff09;MongDB-简介和安装 1、NoSQL简介 MongDB为什么要用呢&#xff1f;之前我们用MySQL数据库&#xff0c;如果数据达到一定的量级&#xff0c;或者有高…

QT 之SQLite数据库

文章目录一、windows下使用命令行方法操作db文件1、 安装sqlite2、 使用sqlite二、QT操作sqlite1、 建立数据库2、 打开数据库3 、关闭数据库4、 创建数据表5 、插入数据6、 删除表数据7、 修改表数据8、 查询数据——遍历查询、条件查询一、windows下使用命令行方法操作db文件…