【人生苦短,我学 Python】进阶篇——类与继承(Day14)

举报
AI 菌 发表于 2021/08/04 23:50:04 2021/08/04
【摘要】 写在前面:大家好!我是【AI 菌】,一枚爱弹吉他的程序员。我热爱AI、热爱分享、热爱开源! 这博客是我对学习的一点总结与记录。如果您也对 深度学习、机器视觉、算法、Python、C++ 感兴趣,可以关注我的动态,我们一起学习,一起进步~ 我的博客地址为:【AI 菌】的博客 我的Github项目地址是:【AI 菌】的Github -> 前往【人生苦短,我...

写在前面:大家好!我是【AI 菌】,一枚爱弹吉他的程序员。我热爱AI、热爱分享、热爱开源! 这博客是我对学习的一点总结与记录。如果您也对 深度学习、机器视觉、算法、Python、C++ 感兴趣,可以关注我的动态,我们一起学习,一起进步~
我的博客地址为:【AI 菌】的博客
我的Github项目地址是:【AI 菌】的Github

-> 前往【人生苦短,我学 Python】总目录 <-

一、类

(1) 什么是类

Python是一种面向对象的编程语言。在面向对象编程中,我们会编写表示现实世界中的事物和情景的,并基于这些类来创建对象

编写类时,你需要定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。

根据类来创建对象被称为实例化 ,这让你能够使用类的实例。通过本文,你将学习到一下一些内容:

  • 编写一些类并创建其实例
  • 指定可在实例中存储什么信息,定义可对这些实例执行哪些操作
  • 编写一些类来扩展既有类的功能,让相似的类能够高效地共享代码
  • 编写的类存储在模块中,并在自己的程序文件中导入其他程序员编写的类

(2) 创建类

使用类几乎可以模拟任何东西。下面来编写一个表示人类的简单类 Human —— 它表示的不是特定的人,而是任何人。

任何人都有名字name和年龄age,我们就可以用name和age来简单地描述Human的属性;任何人都会吃东西eating和运动exercise,所以这些行为可以描述Human的通用方法。

我们在类中封装好这些属性和方法,就能简单地构建一个Human类了。如下所示:

class Human(): """模拟创建人""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def eat(self): """模拟吃东西""" print(self.name + "is eating") def exercise(self): """模拟运动""" print(self.name + "is doing some sports")

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

下面来着重解释一下,创建类过程中的一些重要步骤:

  • def __init__(self, name, age):,这是构造函数。每当你使用 Human 类创建新实例时,Python 都会自动运行它。在构造函数的定义中,形参 self 必不可少,还必须位于其他形参的前面。这是因为 Python 调用这个 __init__() 方法来创建 Human 实例时,将自动传入实参 self 。每个与类相关联的方法调用都自动传递实参 self ,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
  • 5、6行分别定义的两个变量都有前缀 self 。以 self 为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。 self.name = name 获取存储在形参 name 中的值,并将其存储到变量 name 中,然后该变量被关联到当前创建的实例。 self.age = age 的作用与此类似。像这样可通过实例访问的变量称为属性
  • Human 类还定义了另外两个方法: eat() 和 exercise() 。由于这些方法不需要额外的信息,如名字或年龄,因此它们只有一个形参 self 。我们后面将创建的实例能够访问这些方法。

(3) 创建实例

创建好了一个类,并不代表你在程序中就执行了该类。类真正起作用的时候,是其实例化的过程。下面来创建一个表示特定人的实例对象:

# 创建实例
man = Human("AI Jun", 18)

  
 
  • 1
  • 2

创建实例对象后,我们可以访问其属性和方法了:

1、访问属性。要访问实例的属性,可使用句点表示法,使用方法如下:

# 创建实例
man = Human("AI Jun", 18)
# 访问类属性:name和age
print(man.name + " is " + str(man.age) + " years old.")

  
 
  • 1
  • 2
  • 3
  • 4

程序输出结果:

AI Jun is 18 years old.

  
 
  • 1

2、调用方法。根据 Human 类创建实例后,就可以使用句点表示法来调用 Human 类中定义的任何方法。下面来让AI Jun 吃东西(eat)和运动(exercise):

# 创建实例
man = Human("AI Jun", 18)
# 调用方法
man.eat()
man.exercise()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

程序输出结果:

AI Jun is eating
AI Jun is doing some sports

  
 
  • 1
  • 2

二、继承

(1) 什么是继承

编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用 继承 。一个类 继承 另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为 父类 ,而新类称为 子类 。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

(2) 创建继承

创建子类的实例时, Python 首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法 __init__() 需要父类施以援手。

下面我们来创建Human类的一个子类——超人类SuperMan。超人是一类特殊的人,拥有着和Human类一样的属性和方法,但是SuperMan类会一些特异功能,比如会飞fly()。

因此我们可以在前面创建的 Human 类的基础上创建新的SuperMan类,这样我们就只需为电动汽车特有的属性和行为编写代码。

下面来创建一个简单的 SuperMan类,它继承了 Human 类的所有功能:

# 声明父类
class Human(): """模拟创建人""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def eat(self): """模拟吃东西""" print(self.name + "is eating") def exercise(self): """模拟运动""" print(self.name + "is doing some sports")

# 创建子类
class SuperMan(Human): """模拟创建超人""" def __init__(self, name, age): """ 初始化父类的属性""" super().__init__(name, age) # 新增属性 self.weight = 60 # 新增方法 def fly(self): """模拟飞行""" print(self.name + " is flying")

# 子类实例化
super_man = SuperMan('SteelMan', 20)
# 访问子类属性
print(super_man.name + " is " + str(super_man.weight) + " kg")
# 调用子类方法
super_man.fly()

  
 
  • 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

程序输出:

SteelMan is 60 kg
SteelMan is flying

  
 
  • 1
  • 2

定义子类时,必须在括号内指定父类的名称。super() 是一个特殊函数,它帮助 Python 将父类和子类关联起来。这行代码让 Python 调用 SuperMan 的父类的方法 __init__() ,让 SuperMan 实例包含父类的所有属性。父类也称为超类(superclass),名称 super 因此而得名。

(3) 重写父类方法

有的情况下,子类并不需要严格继承父类的方法,这个时候可以在子类中,对部分方法进行重写,给方法与父类方法同名。这样, Python 将不会考虑这个父类方法,而只关注你在子类中定义的相应的方法。

比如在上面的例子中,父类Human有着一个方法eat(),但是超人并不需要吃饭,因此在定义子类时,我们可以对其方法进行重写。下面演示了一下这种重写方式:

# 创建子类
class SuperMan(Human): """模拟创建超人""" def __init__(self, name, age): """ 初始化父类的属性""" super().__init__(name, age) # 新增属性 self.weight = 60 # 重写方法 def eat(self): print("Superman doesn't need to eat !")

# 实例化 
super_man = SuperMan('SteelMan', 20)
# 调用子类重写方法
super_man.eat()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

重写eat()后,如果再调用方法 eat() , Python 将忽略父类中的方法,转而运行上述代码。程序输出如下:

Superman doesn't need to eat !

  
 
  • 1

三、导入类

为了使代码尽可能地整洁, Python 允许你将类存储在模块中,然后在主程序中导入所需的模块。

(1) 导入单个类

我们先将上述类存放在一个名为human.py的文件中,也可以将此文件称之为模块。文件中内容如下:

"""一个用来模拟人的类"""
# 声明父类
class Human(): """模拟创建人""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def eat(self): """模拟吃东西""" print(self.name + "is eating") def exercise(self): """模拟运动""" print(self.name + "is doing some sports")

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

接下来,我们想在主程序文件main.py中导入这个类,并实例化对象:

# 从模块中导入类
from human import Human
# 实例化对象
man = Human("AI Jun", 18)
# 调用方法
man.eat()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(2) 从一个模块中导入多个类

通常,在一个模块中,会包含一些功能相关联的几个类。在下面的human.py模块中,存在两个类:一个父类Human和一个子类SuperMan。

# 声明父类
class Human(): """模拟创建人""" def __init__(self, name, age): """初始化属性name和age""" self.name = name self.age = age def eat(self): """模拟吃东西""" print(self.name + " is eating") def exercise(self): """模拟运动""" print(self.name + " is doing some sports")

# 创建子类
class SuperMan(Human): """模拟创建超人""" def __init__(self, name, age): """ 初始化父类的属性""" super().__init__(name, age) # 新增属性 self.weight = 60 # 新增方法 def fly(self): """模拟飞行""" print(self.name + " is flying") # 重写方法 def eat(self): print("Superman doesn't need to eat !")

  
 
  • 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

接下来,我们在主程序文件main.py中来导入这两个类,并实例化对象:

from human import Human, SuperMan
man = Human("AI Jun", 18)
superman = SuperMan("SteelMan", 200)
man.eat()
superman.eat()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

程序输出:

AI Jun is eating
Superman doesn't need to eat !

  
 
  • 1
  • 2

当需要导入一个模块中的所有类时,可以直接用*号代替所有的类名:

from 模块名 import *

  
 
  • 1

但是,在实际开发过程中,不太建议使用这种方法。因为如果你不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误。

注:同时导入多个类时,要用逗号分隔了各个类。


-> 回到【人生苦短,我学 Python】总目录 <-

在这里插入图片描述
由于水平有限,博客中难免会有一些错误,有纰漏之处恳请各位大佬不吝赐教!

文章来源: ai-wx.blog.csdn.net,作者:AI 菌,版权归原作者所有,如需转载,请联系作者。

原文链接:ai-wx.blog.csdn.net/article/details/113785655

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。