Python基础教程:第十章 面向对象(一)【面向对象基础】

面向对象

学习目标:

  • 理解使用对象完成数据组织的思路

生活中数据的组织

学校开学,要求学生填写自己的基础信息,每人发一张白纸,让学生自己填,这种操作场景下,你会发现,学生填的内容呢是各式各样的,由于我们没有统一的规范,所以说这个信息组织起来是非常的混乱,如果改为登记表,打印出来让学生自行填写,整体上来看效果:整洁明了。通过这个生活中的小案例,我们能够体会到对数据的组织是不是至关重要?那么问题来了,现在是信息化的时代,我们很多时候都不再使用纸质的表单来进行信息的记录了,而是转移到电脑系统中。

程序中数据的组织

那么我们想一下,在我们的程序中又如何组织呢?首先我们来看一个反面教材,我们的程序它有非常多的数据类型,那么所以我们组织数据的形式也是多种多样,比如你可以使用字典来去维护学生的信息,你也可以使用字符串去维护,也可以使用列表去维护,那这种形式多种多样就会造成我们信息组织的混乱和不统一。

 
 
 
 

student_1 ={
"姓名":"周杰轮",
"性别":"男",
"国籍":"中国",
"籍贯":"台湾省",
"年龄":33
}

student_2="我叫林军杰,今年31岁,男的,来自中国山东省"

student_3 =[
"邓紫旗",
"中国",
"北京市",
26,
"女"
]

多种多样就会造成我们信息组织的混乱和不统一,使用变量记录数据太乱了。

如果程序中也和生活中一样,可以设计表格,可以将设计的表格打印出来,可以将打印好的表格供人填写内容,那么数据的组织就非常方便了。

使用对象组织数据

如果我们把步骤分为三步,在生活中是设计表格,打印表格和填写表格,那么对应着在我们程序中就会有设计类,创建对象和对象属性赋值。在我们生活中你去设计一张表格的话,我们在成语中就叫做设计一个类class,我们可以通过 class 这个关键字给上类名,并且在类的内部去定义变量,用变量来去帮助我们去记录数据。

下面分别来看一下:

1. 在程序中设计表格,我们称之为:设计类(class)

 
 
 
 

class Student:
name = None #记录学生姓名

2.在程序中打印生产表格,我们称之为:创建对象

 
 
 
 

# 基于类创建对象
stu_1 = Student()
stu_2 = Student()

3.在程序中填写表格,我们称之为:对象属性赋值

 
 
 
 

stu_1.name = "周杰轮" # 为学生1对象赋予名称属性值
stu_2.name = "林军杰" # 为学生2对象赋予名称属性值

比如我们构建出来的对象,它里面有一个叫做name的变量,为什么会有name呢,就是因为我们在设计类的时候,提供了name变量用来记录学生姓名, 我们在拿到对象之后呢,就可以通过对象变量名的形式,为它赋予具体的值了,看起来是不是和我们生活中的打印表格这种行为还是比较相像的呀!

生活中或是程序中,我们都可以使用设计表格、生产表格、填写表格的形式组织数据。

成员方法

学习目标

  • 掌握类的定义和使用语法

  • 掌握成员方法的使用

  • 掌握self关键字的作用

类的定义和使用

在上一节中,我们简单了解到可以使用类去封装属性,并基于类创建出一个个的对象来使用。

现在我们来看看类的使用语法,如果我们想在程序中去创建一个类的话,首先我们需要通过一个关键字class,通过它就可以定义一个类了,然后在class的后面,我们写上类的名称,以及写上一个我们的老朋友冒号,在冒号下面呢,我们就可以写上类的内容体了,如下格式所示:

 
 
 
 

class 类名称:
类的属性
类的行为

class是关键字,表示要定义类了

  • 类的属性,即定义在类中的变量(成员变量)

  • 类的行为,即定义在类中的函数(成员方法)

 

那么再来看一下,如果你想要拿到类的具体的对象,怎么做?其实也很简单,我们写上类的名称,然后写上一个括号,就表明创建出来了一个具体的类的对象了,那么你可以通过等号赋值在前面通过一个对象去接收它就可以了。创建类对象的语法:

 
 
 
 

对象 = 类名称()

这是简单的类的定义语法以及创建类对象的语法。

通过语法,其实我们可以知道类里面其实就两类,一个是属性,可以称之为数据,第二类就是行为,我们可以称之为函数了。

类里面包含属性,我们在上节中已经见识过了,那类里面包含行为又是个什么样子的,来让我们看一下。

成员变量和成员方法

来看下面的例子:

 
 
 
 

class Student:
name = None # 学生的姓名
age = None # 学生的年龄

def say_hi(self):
print(f"Hi大家好,我是{self.name}")

stu = Student()
stu.name="周杰轮"
stu.say_hi() # 输出:Hi大家好,我是周杰轮

可以看出,类中:

不仅可以定义属性用来记录数据

也可以定义函数,用来记录行为 其中:

  • 类中定义的属性(变量),我们称之为:成员变量

  • 类中定义的行为(函数),我们称之为:成员方法

好,那么从今天开始我们就要改个口了,我们从今天开始定义在类内部的函数,我们就称之为它们叫方法了。

那所以以后我提到函数,大家要明白,函数就是写到类外面的,那么当我在提到方法的时候,同学们要反应过来,我所说的方法指的就是类内部的函数,但以后我们就不会再把类内部的函数叫函数了,而是叫做方法。

成员方法的定义语法

在类中定义成员方法和定义函数基本一致,但仍有细微区别:

 
 
 
 

def 方法名(self,形参1,...,形参N):
方法体

可以看到,在方法定义的参数列表中,有一个:self关键字

self关键字是成员方法定义的时候,必须填写的。

  • 它用来表示类对象自身的意思

  • 当我们使用类对象调用方法的是,self会自动被python传入

  • 在方法内部,想要访问类的成员变量,必须使用self

 
 
 
 

def say_hi(self):
print(f"Hi大家好,我是{self.name}")

注意事项

self关键字,尽管在参数列表中,但是传参的时候可以忽略它,比如:

 
 
 
 

class Student:
name = None
def say_hi(self):
print("He11o大家好")

def say_hi2(self,msg):
print(f"Hello大家好,{msg}")
stu = Student()
stu.say_hi() # 调用的时候无需传参
stu.say_hi2("很高兴认识大家")#调用的时候,需要传msg参数

我们可以看一下来,在我们的类中定义了两个成员方法,那么这两个成员方法一个是一个不带参数的,其实严格来说它有个self,但是这个是自动传的,所以你当它不存在,所以你可以认为它没有定义传入参数。

那第二个它定义了一个 msg 的传入参数。

好,那么你来看一下,当我们调用的时候,第一个这个 say_hi,我们调用它直接给空参就行了,不需要传参。你会发现这个 self 我们压根没有理会它,但是没关系,它可以正常执行。可以看到,在传入参数的时候,self是透明的,可以不用理会它。

类和对象

学习目标

  • 掌握使用类描述现实世界事物的思想

  • 掌握类和对象的关系

  • 理解什么是面向对象

现实世界的事物和类

 

 

现实世界的事物也有属性和行为,类也有属性和行为。

使用程序中的类,可以完美的描述现实世界的事物。

好,你再来回到物上面,我们的物,比如说手机,它同样属性的行为一个不少属性是长宽、高重量、厂商型号,行为是打电话、上网和拍照。又或者说我们再换一个物,比如说有一种生物叫做小狗,那它的属性和行为也是一样,不少属性是身高体重品种,行为就是汪汪叫、吃东西和睡觉。

类和对象

你会发现,在现实世界中,无论是人还是物,都可以总结为两个特征:属性和行为。那么,同学们可能会想,我们前面学习的类是否也有属性和行为?

通过对比,我们会发现,使用程序中的类可以完美地描述现实世界中的事物。好的,到这里,同学们可能会想到我们前面学习的通过类创建具体对象的过程,这里可能有些不太理解。为什么呢?我们刚刚不是说类已经能够完美地描述现实世界中的事物了吗?那么,为什么还要创建对象才能使用呢?

基于类创建对象的语法:

 
 
 
 

对象名 = 类名称()

为什么非要创建对象才能使用呢?

类只是一种程序内的“设计图纸”,需要基于图纸生产实体(对象),才能正常工作

这种套路,称之为:面向对象编程。

使用类和对象描述现实事物

比如在我们的现实生活中,我们想要生产事物,假设我们要生产一个闹钟,那你在生产之前是不是需要有设计图纸?那图纸中是不是规划了我们闹钟的一些属性,比如说厚度有多少,尺寸有多大,以及规划了他的行为,比如他可以响铃,那么当我们有了设计图纸之后,那才会开足生产线,把闹钟一个个的都生产出来一堆的实体。

在程序中通过类来描述

你可以想象一下,这种行为和我们在编写程序时设计类并创建对象非常相似。例如,我们可以设想一个闹钟类,其中包含属性序列号和价格,以及一个响铃行为。在代码中,我们只需要定义两个成员变量id和price来表示这些属性,然后定义一个成员方法来实现响铃行为。一旦我们完成了这个类的设计,就可以像生产线一样创建许多具体的闹钟对象了

基于类创建对象

我们之前已经接触过这种语法了,通过类的名称加上一对括号,可以实例化一个具体的对象。例如,基于左边的类,我们基于该设计图构建了两个闹钟,即clock1和clock2对象。这种操作是面向对象编程的基本套路,核心是设计类,创建对象并让对象执行具体的工作。因此,面向对象编程的本质就是让对象去执行任务。

 

这就是面向对象编程:

设计类,基于类创建对象,由对象做具体的工作

构造方法

学习目标:

  • 掌握使用构造方法向成员变量赋值

属性(成员变量)的赋值

 
 
 
 

class Student:
name = None # 名称
age = None # 年龄
tel = None # 手机号
student1 = Student()
student1.name = "周杰轮"
student1.age = 31
student1.te1 = "18012340000"
student2 = Student()
student2.name = "周杰轮"
student2.age = 31
student2.te1 = "18012340000"

上侧代码中,为对象的属性赋值需要依次进行,略显繁琐。

有没有更加高效的方式,能够一行代码就完成呢?

思考:Student()这个括号,能否像函数(方法)那样,通过传参的形式对属性赋值呢?你看这个语法中是不是写上了类的名称,后面又带上了一个括号,那这个括号是不是我们的老朋友了?我们在调用函数或者说方法的时候,就可以通过括号去传参,那我们想一想在构建类对象的时候,我们能否以传参的形式把我们成员变量的值给它传进去?那如果想实现这个需求是可以的,这个需求就需要通过构造方法来去完成了。

即:init()

构造方法

Python类可以使用:init()方法,称之为构造方法。

可以实现:

  • 在创建类对象(构造类)的时候,会自动执行。

  • 在创建类对象(构造类)的时候,将传入参数自动传递给init方法使用。

比如我们构建一个基础的学生类,并且拥有姓名、年龄和电话三个基础的成员变量。

基于这两个特性,我们在构建类的时候,这个 init 会自动执行,并且我们的参数会自动地提供给这个 init 构造方法去使用。

 
 
 
 

class Student:
name = None # 可以省略
age = None # 可以省略
tel = None # 可以省略
def _init_(self,name,age,tel):
self.name = name
self.age = age
self.tel = tel
print("student类创建了一个对象")

stu=student("周杰轮",31,"18500006666")

  • 构建类时传入的参数会自动提供给init方法

  • 构建类的时候init方法会自动执行

构造方法注意事项

重要的事情说三遍,构造方法名称:init  , 千万不要忘记init前后都有2个下划线

构造方法也是成员方法,不要忘记在参数列表中提供:self

在构造方法内定义成员变量,需要使用self关键字

 
 
 
 

# def __init__(self,name,age,tel):
# self.name = name # 名称
# self.age = age # 年龄
# self.tel = tel # 手机号

这是因为:变量是定义在构造方法内部,如果要成为成员变量,需要用self来表示。

可以用下面的代码再练习一遍:

 
 
 
 

"""
演示类的构造方法
"""
# 演示使用构造方法对成员变量进行赋值
# 构造方法的名称:__init__

class Student:

def __init__(self, name, age ,tel):
self.name = name
self.age = age
self.tel = tel
print("Student类创建了一个类对象")

stu = Student("周杰轮", 31, "18500006666")
print(stu.name)
print(stu.age)
print(stu.tel)

运行结果:

 
 
 
 

Student类创建了一个类对象
周杰轮
31
18500006666

学生信息录入

开学了有一批学生信息需要录入系统,请设计一个类,记录学生的:

姓名、年龄、地址,这3类信息

请实现:

通过for循环,配合input输入语句,并使用构造方法,完成学生信息的键盘录入

输入完成后,使用print语句,完成信息的输出

 
 
 
 

当前录入第1位学生信息,总共需录入10位学生信息
请输入学生姓名:周杰轮
请输入学生年龄:31
请输入学生地址:北京
学生1信息录入完成,信息为:【学生姓名:周杰轮,年龄:31,地址:北京】
当前录入第2位学生信息,总共需录入10位学生信息
请输入学生姓名:

其它内置方法

学习目标:

  • 掌握几种常用的类内置方法

魔术方法

上文学习的init 构造方法,是Python类内置的方法之一。

这些内置的类方法,各自有各自特殊的功能,这些内置方法我们称之为:魔术方法,我们在上一个视频中所学习的 init 构造方法就是 Python 类内置的方法之一,这些内置的类方法各自有各自特殊的功能,所以这些内置方法我们又把它们称之为叫做魔术方法。那么我们在本小节要学习哪些魔术方法?我们主要学习下面4 个。

这个魔术方法只有这 5 个吗?其实并不是, Python 内置的魔术方法是非常非常多的,二三十个还是有的,但是我们在课堂中就没有把它们一一都讲解,我们只要学习几个比较常见的就可以。

str 字符串方法

那首先来我们开始正式学习他们第一个方法,我们把它们叫做字符串方法。你看一下它的名字里面前面 2 个下划线,后面 2 个下划线,你是否会觉得和我们的构造方法一样,其实在我们的 Python 内部,前面 2 个下划线,后面 2 个下划线包围起来的方法,其实我们都可以把它们称之为叫做魔术方法,这是他们的一个命名的规范。

好,那么这个字符串方法有什么作用?来我们看一段示例的代码,我们定义了一个类Student,并且获取了它的类对象,获取完成之后我们直接 print 这个类对象,又或者把这个类对象转变成字符串去输出,那它的结果是一样的。

 
 
 
 

class Student:
def __init__(self,name,age):
self.name = name
self.age = age
student=Student("周杰轮",11)
print(student) # 结果:<_main_.student object at0x000002200cFD7040>
print(str(student)) # 结果:<main_.student object at0x000002200cFD7040>

结果其实表示的是我们当前那个对象的内存地址,好,看起来还是比较高大上的,但是内存地址对于我们来说没什么大的作用,我们一般在开发的过程中也不关心对象的内存地址,那所以说我们可以通过str 这个字符串的内置的魔术方法来去控制我们直接输出这个对象,或者说直接把它转换成字符串的行为。

 
 
 
 

class Student:
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return f"student类对象,name={self.name},age={self.age}"
student=Student("周杰轮",11)
print(student) # 结果:student类对象,name=周杰轮,age=11
print(str(student)) # 结果:student类对象,name=周杰轮,age=11

  • 方法名:str

  • 返回值:字符串

  • 内容:自行定义

lt 小于符号比较方法

 
 
 
 

class Student:
def __init__(self,name,age):
self.name = name
self.age = age
stu1 = Student("周杰轮",11)
stu2 = Student("林军杰",13)
print(stu1 < stu2)

直接对2个对象进行比较是不可以的,但是在类中实现lt方法,即可同时完成:小于符号 和 大于符号 2种比较

 
 
 
 

class Student:
def __init__(self,name,age):
self.name = name
self.age = age
def __lt__(self,other):
return self.age < other.age
stu1 = Student("周杰轮",11)
stu2 = Student("林军杰",13)
print(stu1 < stu2) # 结果:True
print(stu1 > stu2) # 结果:Falue

le 小于等于比较符号方法

魔术方法:le可用于:<=、>=两种比较运算符上。

 
 
 
 

class Student:
def __init__(self,name,age):
self.name = name
self.age = age

def __le__(self,other):
return self.age <= other.age

stu1=Student("周杰轮",11)
stu2=Student("林军杰",13)
print(stu1 <= stu2)#结果:True
print(stu1 >= stu2)#结果:Falue

eq,比较运算符实现方法

 
 
 
 

class Student:
def __init__(self,name,age):
self.name = name
self.age = age
def __eq__(self,other):
return self.age == other.age

stu1 = Student("周杰轮",11)
stu2 = Student("林车杰",11)
print(stu1 == stu2) # 结果:True

  • 不实现eq方法,对象之间可以比较,但是是比较内存地址,也即是:不同对象==比较一定是False结果。

  • 实现了eq方法,就可以按照自己的想法来决定2个对象是否相等了。

猜你喜欢

转载自blog.csdn.net/Blue92120/article/details/130860487