65. Python __init__方法

news2024/12/24 8:35:12

65. __init__方法

文章目录

  • 65. `__init__`方法
    • 1. 知识回顾在类的方法中调用类的属性
    • 2. 知识回顾调用方法时传值
    • 3.体验`__init__`方法
    • 4. `__init__`的作用
    • 5.` __init__`方法的写法
    • 6. `__init__`方法调用类的属性
    • 7. 课堂实操

1. 知识回顾在类的方法中调用类的属性

【目标任务】

创建一个类,计算2个数的和。

【体验代码】

# 定义一个求和类,类名为Sum
class Sum:

    # 直接写在类里的变量称为类属性
    x = 2 
    y = 4
   
    # 在类中定义的函数称为方法
    # 方法名为qiuhe,功能是计算类里2个变量的和
    def qiuhe(self):
        # 方法中的代码块        
        print(x+y)
        
# 创建对象:对象名=类名( )
he= Sum( ) 
# 调用对象:对象名.方法名(值)
he.qiuhe( )

运行上述的代码程序报错,提示name 'x' is not defined即x没有被定义。

观察代码的第5和第6行,我已经给变量赋值了。

# 直接写在类里的变量称为类属性
x = 2 
y = 4

但程序还是提示没有被定义,这是因为xy是在类里定义的变量。

在类里定义的变量我们称之为类属性。

上节课我们学过,在类内部的方法中调用类的属性其它类的方法时,需要在前面加上slef. 如:

self.属性名

self.方法名

# 在类中定义的函数称为方法
# 方法名为qiuhe,功能是计算类里2个变量的和
def qiuhe(self):
    # 方法中的代码块        
    print(x+y)

qiuhe是在类中定义的方法。

x和y是类里的属性。

要调用类里的属性,语法为self.属性名

因此我们将代码的第12行:

# 方法中的代码块        
print(x+y)

更改如下:

# 方法中的代码块        
print(self.x+self.y)

【综合代码】

# 定义一个求和类,类名为Sum
class Sum:

    # 直接写在类里的变量称为类属性
    x = 2 
    y = 4
   
    # 在类中定义的函数称为方法
    # 方法名为qiuhe,功能是计算类里2个变量的和
    def qiuhe(self):
        # 方法中的代码块        
        print(self.x+self.y)
        
# 创建对象:对象名=类名( )
he= Sum( ) 
# 调用对象:对象名.方法名(值)
he.qiuhe()

【终端输出】

6

输出结果为6,我们成功设计了一个求和的小程序。

但这个程序只能计算2和4的和,不方便用户。

用户如果需要计算其他2个数的和,就要更改类的属性。

我们使用类的优势之一在于,代码写好后我们将它封装保存,需要的时候我们直接调用它就好。

因此,我们最好不要取修改类里的代码。

那怎么优化呢?

我们可以通过调用方法时传值的形式进行代码优化。

2. 知识回顾调用方法时传值

# 定义一个求和类,类名为Sum
class Sum:
    
    # 在类中定义的函数称为方法
    # 方法名为qiuhe,功能是计算类里2个变量的和
    def qiuhe(self,x,y):
        # 方法中的代码块        
        print(x+y)
        
# 创建对象:对象名=类名( )
he= Sum( ) 
# 调用对象:对象名.方法名(值)
he.qiuhe(2,4)

【终端输出】

6

和之前的代码相比,我做了如下改动:

  1. 我把类定义属性的语句删除了。
# 直接写在类里的变量称为类属性
x = 2 
y = 4
  1. 我修改了求和方法的参数。

将原来的:

def qiuhe(self):
    # 方法中的代码块        
    print(self.x+self.y)

修改为:

# 在类中定义的函数称为方法
# 方法名为qiuhe,功能是计算类里2个变量的和
def qiuhe(self,x,y):
    # 方法中的代码块        
    print(x+y)

和之前的方法相比,我在方法中增加了2个参数,x和y。

最后再调用方法的时候直接传入方法中需要的值。

# 调用对象:对象名.方法名(值)
he.qiuhe(2,4)

方法中的值是按位置进行传递的。

2传递给x。

4传递给y。

方法传值的优势在于不管你想计算哪两个数的和,只需要修改方法中的值即可。

【体验代码】

观察下面的代码,只用修改值我们就可成功计算出多个两位数的和。

# 定义一个求和类,类名为Sum
class Sum:
    
   # 在类中定义的函数称为方法
   # 方法名为qiuhe,功能是计算类里2个变量的和
    def qiuhe(self,x,y):
        # 方法中的代码块        
        print(x+y)
        
# 创建对象:对象名=类名( )
he= Sum( ) 
# 调用对象:对象名.方法名(值)
he.qiuhe(2,4)
he.qiuhe(4,4)
he.qiuhe(7,4)

【终端输出】

6
8
11

3.体验__init__方法

我们还可以继续优化我们的代码:

观察下面的代码,重点注意观察第6行。

# 定义一个求和类,类名为Sum
class Sum:
    
    # 在类中定义的函数称为方法
    # 方法名为__init__
    def __init__(self,x,y):        
        # 方法中的代码块        
        print(x+y)
        
# 创建对象:对象名=类名( )
he= Sum(2,4) 

【终端输出】

6

上面的代码较之前的代码,我做了如下几个调整:

  1. 把之前的函数名qiuhe修改为__init__

下面是之前的旧代码:

# 定义一个方法,计算类里2个变量的和
def qiuhe(self,x,y):
    # 方法中的代码块        
    print(x+y)

下面是修改后的代码:

def __init__(self,x,y):
    # 方法中的代码块        
    print(x+y)
  1. 把要传递的值放入创建对象的语句里,删除了调用方法的代码。

之前的旧代码,有调用方法语句,传入的值在调用方法语句里。

# 创建对象:对象名.类名( )
he= Sum( ) 
# 调用对象:对象名.方法名(值)
he.qiuhe(2,4)

现在的代码只有创建对象语句,传入的值在创建对象语句里。

# 创建对象:对象名=类名(值)
he= Sum(2,4) 

之前说过,要输出类方法里的语句,是需要一个调用方法的语句的。

那为什么这里修改方法名后,不调用也能输出呢。

那是因为__init__方法的作用就是,在类创建对象时,不需要调用方法语句,就可以自动执行__init__方法中的代码块(这是我自己对该方法的解释,仅供参考)。

大家可以试一下,同样的情况下,如果方法名不为__init__,程序是会报错的:

# 定义一个求和类,类名为Sum
class Sum:
    
    # 在类中定义的函数称为方法    
    def qiuhe(self,x,y):
        # 方法中的代码块        
        print(x+y)
        
# 创建对象:对象名=类名( )
he= Sum(2,4) 

【终端输出】

TypeError: Sum() takes no arguments

运行上述代码,程序报错,提示Sum() takes no arguments即Sum不接受参数。

同样的代码,方法名不一样,输出结果就不一样,这就是__init__方法在作怪。

4. __init__的作用

Python本身有内置函数和自定义函数两种。

自定义函数我们可以根据自己的喜好命名。

但内置函数就不能随便更改名字。只有单词拼写正确了,我们才能使用该函数本身具有的功能。例如type、input、print函数。

其实类中也可以这样理解。

上节课我用的drive ,stop,back都是我自己定义的方法名。

这里的 __init__我们可以理解成它是类中的内置方法,方法名是固定的。

init是initialization的缩写。

initialization [ɪˌnɪʃəlaɪ’zeɪʃn] :初始化。

__init__方法通常称为初始化方法。

__init__方法的作用官方解释是支持带参数类的初始化,声明该类的属性(类中的变量)。

如果你是小白,这样的话术很难理解。

那我们可以这样理解它:

类中的属性不是一成不变的,是一个可能会变化的值。

我们不想在类中定义属性,而想在创建对象时传入,这时可以用init方法在类中声明属性即类里的变量。

当然我还有一种简单粗暴的理解。

你就把它当做一个类中的普通方法,这个方法有以下几个作用:

1. init方法接收创建对象时传入的值。

2. init方法中的代码块不需要调用语句,创建对象就会被自动执行。

【举例说明】

class Test:
    
    def __init__ (self):
        print("只要有创建对象语句,我就会被输出。")
    
    def A(self):               
        print("要调用方法A,我才输出。")
        
# 创建对象:对象名=类名( )
ceshi= Test( )

【终端输出】

只要有创建对象语句,我就会被输出。

上述代码因为只有创建对象语句,没有调用方法语句。

因此,下面这个语句被输出了,因为init方法中的代码块会自动被执行。

print("只要有创建对象语句,我就会被输出。")

下面的语句没有输出,因为没有调用方法A。

print("要调用方法A,我才输出。")

【增加一个调用方法A的语句】

class Test:
    
    def __init__ (self):
        print("只要有创建对象语句,我就会被输出")
    
    def A(self):               
        print("要调用方法A,我才输出。")

# 创建对象:对象名=类名( )
ceshi= Test( )
# 调用方法:对象名.方法名
ceshi.A()

【终端输出】

只要有创建对象语句,我就会被输出
要调用方法A,我才输出。

两句话都被输出了,因为我增加了调用方法A的语句,如下:

# 调用方法:对象名.方法名
ceshi.A()

5. __init__方法的写法

定义__init__方法的语法和定义其它方法的语法是一样的。

有两个需要特别注意的地方。

  1. 方法名是init,很多初学者容易错写成int

  2. 方法名前后格有2条小横线,注意是前面2条,后面2条,总的4条。初学者易写成2条小横线。

在这里插入图片描述

6. __init__方法调用类的属性

这是我刚才写的代码:

# 定义一个求和类,类名为Sum
class Sum:
    
    # 在类中定义的函数称为方法
    # 方法名为__init__
    def __init__(self,x,y):        
        # 方法中的代码块        
        print(x+y)
        
# 创建对象:对象名=类名( )
he= Sum(2,4) 

上述的代码运行虽然没有错误,但其实是不规范的。

下面的代码是规范的:

# 定义一个求和类,类名为Sum
class Sum:  

    # 在类中定义的函数称为方法
    # 方法名为__init__
    def __init__(self,x,y):
        self.x = x
        self.y = y              
        # 方法中的代码块        
        print(self.x+self.y)
        
# 创建对象:对象名=类名( )
he= Sum(2,4) 

【终端输出】

6

我是这样理解的,仅供大家参考:

2和4是在创建对象时传入的值,理论上等同于类的属性。

是类的属性,在类中调用类的属于就需要用self.属性名

上述方法有self,x,y三个参数。

self.x中的x表示的是类的属性。

等号后面的x表示的是值。

self.属性=值

self.x = x
self.y = y 

在这里插入图片描述

按照位置,2传递给x。self.x相当于类里的变量x。

按照位置,4传递给y。self.y相当于类里的变量y。

按照语法规则在init中我们是要带着self.走的。

但没有目前也没有报错。

至于为什么没报错,或者self.在这里存在的意义我目前还没有语言给大家解释清楚。

但建议所有学者都带上self.,我相信存在既有意义,只是我水平不够,解释不清楚。

7. 课堂实操

下面是我们上节课生产各种汽车的代码:

# 定义一个车类,类名为Cars
class Cars:

    # 直接写在类里的变量称为类属性
    color_1 = "红色"
    color_2 = "黑色"
    color_3 = "黄色"
    color_4 = "绿色"
    type_1 = "小轿车"
    type_2 = "越野车"
    type_3 = "公交车"
    type_4 = "跑车"
   
    # 在类中定义的函数称为方法
    # 方法的第1个参数必须是slef    
    def drive(self, speed):
        # 方法中的代码块
        print(f"经测试,{self.color_4}{self.type_4}的最高时速是{speed}公里每小时。")
        print("经测试,{}的{}的最高时速是{}公里每小时。".format(self.color_2, self.type_4, speed))
        print("经测试,{}的{}的最高时速是{}公里每小时。".format(self.color_1, self.type_4, speed))
# 创建对象:对象名=类名( )
paoche = Cars( )      

# 调用对象:对象名.方法名(值)
# 测试车速
paoche.drive(230)

【终端输出】

经测试,绿色的跑车的最高时速是230公里每小时。
经测试,黑色的跑车的最高时速是230公里每小时。
经测试,红色的跑车的最高时速是230公里每小时。

下面,我对上面的代码就行优化:

# 定义一个车类,类名为Cars
class Cars: 
   
    # 使用初始化方法init  
    def __init__(self, color, type, speed):
        self.color = color
        self.type = type
        self.speed =speed
        # 方法中的代码块
        print(f"经测试,{self.color}{self.type}的最高时速是{self.speed}公里每小时。")        
        
# 创建对象:对象名=类名( )
che = Cars("红色","公交车",160 )       
che = Cars("黑色","跑车",280 )   
che = Cars("黄色","卡车",180 )   
che = Cars("紫色","小轿车",240)   
che = Cars("黑色","小轿车",240) 
che = Cars("红色","小轿车",240) 
che = Cars("绿色","小轿车",240) 

【终端输出】

经测试,红色的公交车的最高时速是160公里每小时。
经测试,黑色的跑车的最高时速是280公里每小时。
经测试,黄色的卡车的最高时速是180公里每小时。
经测试,紫色的小轿车的最高时速是240公里每小时。
经测试,黑色的小轿车的最高时速是240公里每小时。
经测试,红色的小轿车的最高时速是240公里每小时。
经测试,绿色的小轿车的最高时速是240公里每小时。

对比2段代码,大家应该能感受到init方法的优势了。

终端输出了7个语句,即生产了7种汽车。

如果我们没有用init方法,要输出上面的这7个语句。

我们需要定义7个颜色变量,7个汽车类型变量,7个汽车时速变量,写7带字符串格式化的输出语句。

而用init方法,代码就相对简洁了很多。

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

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

相关文章

C++程序设计——类的六个成员函数

类的六个成员函数 空类中真的什么都没有吗? 事实上任何一个类,在我们不写的情况下,都会自动生成6个默认的成员函数。 1.构造函数 概念: 构造函数是一个特殊的成员函数,名字与类名相同,实例化对象时由编译器…

【基于机械臂触觉伺服的物体操控研究】几种轨迹规划的算法及代码实现

我的毕设题目定为《基于机械臂触觉伺服的物体操控研究》,这个系列主要用于记录做毕设的过程。 轨迹规划是机器人绕不过去的话题,其目的是为了让机器人的运动更加的平滑。对于四足机器人,贝赛尔曲线的应用比较普遍。而对于机械臂,…

【C++】C++ 入门(一)

目录 一、前言 1、什么是C 2、C关键字(C98) 二、第一个C程序 三、命名空间 1、存在意义 2、命名空间定义 3、命名空间的使用 3.1、指定命名空间访问 3.2、全局展开访问 3.3、部分展开访问 四、C输入&输出 五、缺省参数 1、缺省参数概念 2、缺省参数分类 2.…

【Day4】24两两交换链表中的节点、19删除链表的倒数第N个节点、链表相交、142环形链表Ⅱ

【Day4】24两两交换链表中的节点、19删除链表的倒数第N个节点、160链表相交、142环形链表Ⅱ24.两两交换链表的点19.删除链表的倒数第N个节点160链表相交 面试题02.07142 环形链表Ⅱ判断链表是否有环若链表有环,如何找到环的入口24.两两交换链表的点 题目链接&#…

Spacedesk 安装教程及连接后黑屏解放方法

spacedesk 安装教程1. Spacedesk 概述2. Spacedesk 安装教程2.1 下载 Spacedesk2.2 连接计算机的 Spacedesk3. 被拓展的设备连接后黑屏的解决方法结束语1. Spacedesk 概述 Spacedesk 是一款低延迟的免费显示器拓展软件,且不需要线材将不同设备连接; Spa…

MySQL中的普通索引和唯一索引实际开发中的选择

文章目录前言一、普通索引和唯一索引介绍二、查询语句的比较三、更新语句的比较四、索引的选择和实践前言 本文我们将会从针对普通索引与唯一索引的增删改查的具体执行流程,来看看效率的对比。以便让我们在实际业务开发中可以进行更好的选择。 一、普通索引和唯一索…

动态规划系列 —— 背包问题

什么是背包问题 背包问题是有N件物品,容量为V的背包 每个物品有两个属性:体积,价值,分别用数组v,w表示 第i件物品的体积为v[i],价值为w[i] 计算在背包装得下的情况下,能装的最大价值是多少&…

MATLAB 图像处理大作业

1、基础知识利用 MATLAB 提供的 Image file/IO 函数完成以下处理:(a)以测试图像中心为圆心,图像长宽中较小值一半为半径画一个红颜色的圆;(b)将测试图像涂成国际象棋状的‘黑白格’样子&#xf…

华芯片特微 M33内核 KEIL5环境配置不上问题

1 JFLASH连接不上问题 官方手册有说解决这个问题 2 JFLASH能连接上KEIL提示no found sw-dp 在替换keil下载算法后还是提示no found sw-dp 1 怀疑是keil 527版本太高了, 就换了518 还是不行 2 怀疑是keil检测到盗版了就不让下, 替换Jlink为以前老版本还是不行 解决方案: 下…

聊天气泡图片的动态拉伸、适配与镜像

聊天气泡图片的动态拉伸、适配与镜像前情提要创建.9.png格式的图片从资源文件夹加载.9.png图片从本地文件加载“.9.png”图片项目痛点进阶探索iOS中的方式Android中的探索构造chunk数据构造padding数据镜像翻转功能屏幕的适配简单封装演示示例一条线段控制的拉伸两条线段控制的…

Pandas 安装与教程

前言Pandas 是 Python 语言的一个扩展程序库,用于数据分析。Pandas 是一个开放源码、BSD 许可的库,提供高性能、易于使用的数据结构和数据分析工具。Pandas 名字衍生自术语 "panel data"(面板数据)和 "Python data…

[apidoc]Apidoc-文档生成工具

Apidoc主要是用于生成API文档的工具,可以用于多种语言,包括java、javascript、php等 这里主要是为了写前端的APIDOC,方便交互是双方的使用; 工具的安装 工具包的安装 npm i apidoc [-g|-D]可以-g全局安装,或者-D局部安装,因为…

网盘系统|基于SpringBoot的网盘系统的设计与实现

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

【无功优化】考虑泄流效应的光伏并网点电压系统侧无功优化(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

软考中级,【软件评测师】经验分享

,以下是我的考试成绩,一次通过很是幸运,希望把我的好运传递给大家,大家都能一次通过谈经验之前,先和大家说说考试的题型以及考试的内容,根据往年的考试题目我们可以很容易得知,软件评测师考试分…

Cisco(62)——PBR策略路由案例

场景1-单下一跳: 拓扑: 需求: R1和R2均连接100.100.100.100,R4看做一台PC,当PC访问100.100.100.100的时候优先走左边,当左边down掉之后切换到右边链路,使用PBR操作。 实现: 1.IP地址等基本配置 R4: R4(config)#no ip routingR4(config)#int e0/0 R4(config-if)#ip add…

Typora自动上传文章图片太难折腾?十三行JavaScript代码足矣

前言 Typora是我用过最爽的markdown文本编辑器了。但是有一点很让人难受,就是在写文章的时候,粘贴上的图片是本地路径。这就导致在复制文章到各大博客平台时发表,图片无法显示。然后需要各种办法去处理文章中的图片,不仅要手动上传…

【学习笔记】【Pytorch】十、线性层

【学习笔记】【Pytorch】九、线性层学习地址主要内容一、前言二、Pytorch的线性层三、Linear类的使用1.使用说明2.代码实现学习地址 PyTorch深度学习快速入门教程【小土堆】. 主要内容 一、前言 在神经网络中,我们通常用线性层来完成两层神经元间的线性变换。 …

【C++】面向对象---继承(万字详解)

目录前言一、继承的定义及概念二、继承方式三、基类和派生类之间的转换四、切片五、继承中的作用域六、派生类中的默认成员函数七、继承中的友元与静态成员继承与友元继承中的静态成员八、棱形继承和虚继承棱形继承虚继承总结前言 继承是面向对象的一个重点,而继承…

活动星投票医疗保障案例推介网络评选微信的投票方式线上免费投票

“医疗保障案例推介”网络评选投票_线上免费投票系统_功能齐全的微信投票_在线免费投票用户在使用微信投票的时候,需要功能齐全,又快捷方便的投票小程序。而“活动星投票”这款软件使用非常的方便,用户可以随时使用手机微信小程序获得线上投票…