文章目录

  • Python 面向对象编程
    • 1.3.1 面向对象编程理论
      • 1.3.1.1 对象
      • 1.3.1.2 类
      • 1.3.1.3 面向对象编程的特点
    • 1.3.2 Python 面向对象编程
      • 1.3.2.1 Python 类与对象
      • 1.3.2.2 类与对象中的变量
      • 1.3.2.3 类与对象中的函数
      • 1.3.2.4 \_\_init\_\_ 方法
    • 1.3.3 万物皆对象
      • 1.3.3.1 重识变量
      • 1.3.3.2 重识常量
      • 1.3.3.2 重识函数
      • 1.3.3.3 重识数据结构
      • 1.3.3.4 重识程序
    • 1.3.4 练习
      • 1.3.4.1 重构成绩管理系统

Python 面向对象编程

在北宋时期,毕昇发明了活字印刷术。他先将文字做成一个个汉字模具,然后按照稿件把单字挑选出来,排列在字盘内,涂墨印刷成书,印完后再将字模拆出,留待下次排印时再次使用。活字印刷术相对于文字书写更加简洁高效,它对印刷业的兴起发挥了重大作用,甚至推动了欧洲文艺复兴的发展。

Python 是一种基于面向对象设计的编程语言,它使用“类”与“对象”进行编程。这里“类”就好比汉字模具,“对象”就好比印刷完的书籍。你不需要一次又一次书写复杂重复的程序,只需要提前编写好需要的类,然后通过类产生具有特定功能的对象即可,这大大提高了 Python 编程的简洁性。

下面我们就通过面向对象的角度重新审视 Python 宇宙,相信你可以感受到面向对象带来的代码简化与效率提升。

1.3.1 面向对象编程理论

在之前的代码中,我们往往采用典型的面向过程编程方式,定义很多函数与变量:

## 定义函数:
函数1
函数2
函数3
函数4## 定义变量:
变量1
变量2
变量3
变量4## 通过变量与函数完成操作
变量3 = 函数1(变量1, 变量2)
变量5 = 函数2(变量3, 变量4)

然而当我们要实现的功能越来越复杂,需要添加的函数与变量也就越来越多。每个函数都有不同的功能,有特定的参数与返回结果,每个变量也有不同的表示意义,程序会变得越来越难以维护。而面向对象通过类与对象的方式解决问题:

## 根据功能定义类1
类1:类函数1
变量:变量1变量2## 根据功能定义类2
类2:类函数2类函数3
变量:变量3变量4变量5## 通过对象完成操作
对象1 = 类1()
对象2 = 类2()
对象2.变量5 = 对象2.函数2(对象1.函数1())


面向对象编程的出现,使得变量和函数可以根据功能进行整理分类,通过面向对象的模块化编程,大大减轻了复杂程序的设计与维护负担。

1.3.1.1 对象

在 Python 中一切都是对象,就像在现实世界中一切都是对象。

  • 在现实中:对象可以是有型的,例如一粒米、一名学生、一辆汽车,甚至一个星球。它也可以是无形的,例如一次演出,一场球赛,一次出差。对象可以简单也可以复杂,复杂的对象可以由许多简单的对象构成,整个世界也可以被认为是一个非常复杂的对象。

  • 在 Python 中:对象可以是有型的,例如一个常量,一个变量,一个序列或字典。它也可以是无形的,例如一个函数。对象可以简单也可以复杂,复杂的对象可以由许多的简单对象组成,整个 Python 程序也可以被当作一个对象。

无论在现实中或 Python 中,对象都具有以下三个特性:

  • 每个对象都有一个独特的名字以区别于其他对象。
  • 有属性来描述它的某些特征。
  • 有一组操作,每个操作决定对象的一种行为。

1.3.1.2 类

类是用来定义对象的 “模板”。

  • 在现实中:类是一组具有相同属性和行为的对象的抽象。例如张三、李四虽然每个人有不同的性格与职业,但他们的基本特征是相似的,都有鼻子有眼能吃饭,因此我们统称他们为“人”类,而每一个人就是一个对象。
  • 在 Python 中:类是一组具有相同数据和操作的对象的模板集合。例如“学生”类可以由学号、姓名、性别、成绩等表示其属性的数据项和对这些数据的录入、修改和显示等操作组成,而每一个特定的学生例如 XiaoHu 就是一个对象。

1.3.1.3 面向对象编程的特点

面向对象编程有以下几个基本特征:

  • 抽象:是将有关事物的特征归纳、集中的过程。通过总结不同“对象”的主要特性设计一个“类”,只强调感兴趣的信息,忽略了与主题无关的信息。
  • 封装:是把数据和操作集中在对象内部,并尽可能隐藏对象的内部细节。对象像一个黑匣子,你只要知道它提供的功能,不需要了解其内部的实现方式。
  • 继承:是指一个类可以继承另一个类的特征与功能,并添加自己的特征。例如“吉士堡”继承了“汉堡”类,它有面包、菜与肉,但也有独特的一片芝士。
  • 多态:指不同的对象进行相同操作时产生多种不同的行为方式。例如“打开”电风扇它会旋转,“打开”电脑屏幕会亮,“打开”抽屉柜子门会开,同样是打开操作,不同对象收到指令后的行为方式是不同的。

1.3.2 Python 面向对象编程

到目前为止,我们接触的变量、运算符、函数等概念来源于 “面向过程” 的编程方式。在上一节中,你可能会对 names.append('Cryin') 这种写法感到疑惑,为什么序列变量 names 可以通过符号 . 调用 append 函数?这种编程方式便是面向对象编程,在这里 names 是一个对象,对象拥有很多类似 append 的函数,每个对象都属于某一个类。

下面我们将介绍 Python 中的面向对象编程方法,并以上一节中的学生成绩管理系统为例方便大家理解。

1.3.2.1 Python 类与对象

Python 使用 class 关键字定义类,类似函数,下面的缩进部分构成了类的主体:

## 创建一个 student 类
class student():pass

使用类的名字和一对括号可以创建类的对象:

## 使用 类的名字 student 与 括号() 可以创建类的对象 xiaohu
xiaohu = student()
xiaoming = student()print(type(xiaohu))
print(type(xiaoming))
<class '__main__.student'>
<class '__main__.student'>

1.3.2.2 类与对象中的变量

我们提到类与对象都有包含一组属性与方法,在 Python 中类的变量用于表示类的属性。student 表示学生类,在我们的系统中我们只关注学生的姓名、数学成绩和语文成绩而不考虑其他,分别用类变量 name, Math_score, Chinese_score 表示。这体现了面向对象编程的”抽象性“。

## 创建一个 student 类
class student():## 类的内部定义三个内部变量,并定义他们的初始值name = 'Undefined'Math_score = NoneChinese_score = None

在 Python 中对象拥有与类相同的数据和操作,因此通过类创建的对象也拥有相同的变量。我们使用 . 符号来引用对象或类的变量与函数:

## 使用 类的名字 student 与 括号() 可以创建类的对象 xiaohu
xiaohu = student()
## 使用 . 符号引用对象xiaohu的变量name、Math_score、Chinese_score
print(xiaohu.name)
print(xiaohu.Math_score)
print(xiaohu.Chinese_score)
Undefined
None
None

这里我们通过类创建对象还仅仅是一个初始值,这里我们可以通过赋值符号改变对象内数据的值:

## 通过赋值符号改变对象内变量的值
xiaohu.name = 'XiaoHu'
xiaohu.Math_score = 65
xiaohu.Chinese_score = 55print(xiaohu.name)
print(xiaohu.Math_score)
print(xiaohu.Chinese_score)
XiaoHu
65
55

在这里我们要注意区分两个概念,类变量与对象变量,在上述代码中 student.name 是类变量,xiaohu.name 是对象变量。

  • 类变量属于类,更改类变量会影响所有后续由该类创建对象的属性。
  • 对象变量属于对象,更改对象变量只影响该对象的属性。
## 更改对象变量只影响该对象的属性。
xiaoming = student()
## 修改 xiaoming.name,xiaohu 的属性不受影响
xiaoming.name = 'XiaoMing'
print(xiaoming.name)
print(xiaohu.name)
XiaoMing
XiaoHu
## 更改类变量会影响所有后续由该类创建对象的属性。
xiaoming = student()
print(xiaoming.name)## 修改 student.name 再次创建新对象 xiaoming
student.name = 'Change Name'
xiaoming = student()## xiaoming.name 不再是 undefined 而是 change name
print(xiaoming.name)
Undefined
Change Name

1.3.2.3 类与对象中的函数

在 Python 中类函数用于表示类的操作,它又被称作为“方法”。它们与之前我们学到的函数类似,但是类函数必须有一个额外的 self 参数:

class student():## 定义类函数时要有一个特殊的 self 参数def print_name(self,):print(self.name)name = 'Undefined'Math_score = NoneChinese_score = None
xiaohu = student()
xiaohu.name = 'Xiaohu'
xiaohu.print_name()
Xiaohu

self 函数用于在类的内部指向对象本身,它是用于连接 类 与 对象 的工具,也是 Python 面向对象编程“多态”特性的一种体现。

例如在上述代码,我们使用 student 类产生对象 xiaohu,那么 self 就代指 xiaohu;如果我们产生对象 xiaoming,那么 self 就会自动代指 xiaoming。因此 self 参数可以根据不同对象产生不同操作,这体现了面向对象编程的“多态性”。

我们还可以给 student 创建一个用于更改成绩的方法,这样我们后续就不需要通过赋值符号更改对象内的数据:

class student():## 定义一个修改对象数据值的函数def change_score(self, course_name, score):if course_name == 'Math':self.Math_score = scoreelif course_name == 'Chinese':self.Chinese_score = score## 如果输入的 course_name 不是 Math 或者 Chinese,则输出错误信息else:print(course_name, " course is still not in current system")def print_name(self,):print(self.name)name = 'Undefined'Math_score = NoneChinese_score = None
xiaohu = student()
xiaohu.name = 'Xiaohu'
xiaohu.change_score('Math', 65)
xiaohu.change_score('Chinese',55)
xiaohu.change_score('Physics',48)
Physics  course is still not in current system

随着系统的迭代,系统的复杂度将会直线上升。假设当我们有了十多种课程后,采用 change_score 函数要比直接为一个个课程的成绩赋值更加优雅,用户不再需要了解 student 类中有定义哪些变量等复杂细节,只需要了解 change_score 函数的用法便可以更改学生成绩,这体现了面向对象编程的“封装性”。

1.3.2.4 __init__ 方法

在之前的代码中,我们采用赋值符号来为对象产生初始值:

xiaohu.name = 'XiaoHu'
xiaohu.Math_score = 65
xiaohu.Chinese_score = 55

然而这种方式或许有些麻烦,其实 Python 类中有一种 __init__ 方法专门用于初始化对象。这个方法在通过类创建对象时被自动调用,并按照你的想法初始化该对象。下面我们通过 __init__ 方法重新定义 student 类:

class student():## 定义 __init__ 方法,通过该方法的参数输入初始值,在该方法内部为变量赋值def __init__(self, name, Math_score, Chinese_score):self.name = nameself.Math_score = Math_scoreself.Chinese_score = Chinese_scoredef change_score(self, course_name, score):if course_name == 'Math':self.Math_score = scoreelif course_name == 'Chinese':self.Chinese_score = score## 如果输入的 course_name 不是 Math 或者 Chinese,则输出错误信息else:print(course_name, " course is still not in current system")def print_name(self,):print(self.name)name = 'Undefined'Math_score = NoneChinese_score = None

在定义了 __init__ 方法后,我们通过在类后面的小括号内传递参数的方式初始化对象:

##
xiaohu = student('XiaoHu',65,55)
xiaohu.print_name()
XiaoHu

1.3.3 万物皆对象

对象是 Python 中最核心的概念,犹如道教中 “一生二,二生三,三生万物”,Python 中万物皆源于对象。下面我们在面向对象编程的角度回顾之前学习的变量、函数以及数据结构。

1.3.3.1 重识变量

在 Python 中所有变量都是对象,下面我们创建一个 int 变量,它有 bit_lenth, conjugate, to_byte, from_byte 等方法。我们测试一下 to_byte 方法:

variable = 1
type(variable)
int

to_byte 将 int 对象转化成 byte 对象 b’\x00x\01’ 因为整数 1 的二进制编码是 0001。

variable_byte = variable.to_bytes(2, byteorder = 'big')
print(variable_byte)
print(type(variable_byte))
b'\x00\x01'
<class 'bytes'>

1.3.3.2 重识常量

Python 中的常量也是对象,其中最常用到对象方法的是字符串常量。

字符串常用方法如下:

  • format(): 用于从其他信息中构造字符串。
  • replace(): 用于替代字符串中的某个字符或子串。
  • split(): 用于通过某种字符分隔字符串。
  • upper(): 把字符串转换成大写。
  • lower(): 把字符串转化成小写。
## format 方法使用 {数字 i} 对应 (第i个变量) 来控制用于构造字符串的参数
print("Learn {0} in a {1} way!!".format('Python','smart'))
print("Learn {0} in a {1} way!!".format('PHP','hard'))
Learn Python in a smart way!!
Learn PHP in a hard way!!
## replace 方法使用一个或多个参数分隔字符串,并返回子串构成的序列
print("Learn Python in a smart way!!".replace('smart','hard'))
Learn Python in a hard way!!
## split 方法使用一个或多个参数分隔字符串,并返回子串构成的序列
print("Learn Python in a smart way!!".split(' '))
['Learn', 'Python', 'in', 'a', 'smart', 'way!!']
## upper 和 lower 方法转化大小写
print("Learn Python in a smart way!!".upper())
print("Learn Python in a smart way!!".lower())
LEARN PYTHON IN A SMART WAY!!
learn python in a smart way!!

1.3.3.2 重识函数

更神奇的是,在 Python 中函数也是对象,因此函数也有自己的数据与方法。

def check_sum(num1, num2, target):## 在 def xxx(): 下面缩进的是函数的内容a = num1b = num2return a + b == target

通过 .__name__ 成员变量可以获得函数的名字:

check_sum.__name__
'check_sum'

1.3.3.3 重识数据结构

现在你可以想象到,数据结构也理所应当是对象。是的,数据结构为我们提供了许多非常的方法!上一节中的 append 就是其中一个。

l = [1,2,3,4]
l.append(5)
print(l)
[1, 2, 3, 4, 5]

除此之外,我们可以通过 pop 方法替代 del 关键字删除序列内某个元素:

l.pop(1)
print(l)
[1, 3, 4, 5]

通过 insert 方法在特定位置增加元素:

## 第一个参数是位置,第二个参数是插入的元素
l.insert(0,1)
print(l)
[1, 1, 3, 4, 5]

同样的,在元组、字典、集合等数据结构中也提供了很多方法,在此将常用的方法总结如下:

  • 列表

    • append(x) 把元素 x 放在入列表尾部
    • count(x) 统计元素 x 在列表中出现次数
    • extent(seq) 把新列表 seq 合并到列表尾部
    • index(x) 返回元素 x 在列表第一次出现的位置
    • insert(index, x) 把元素 x 插入到 index 位置
    • pop(index) 删除并返回 index 所在位置的元素
    • remove(x) 删除出现的第一个 x 元素
    • reverse() 颠倒列表顺序
    • sort() 对列表进行排序
  • 字典

    • clear() 清楚字典内所有元素
    • copy() 返回字典的一个复制
    • has_key(key) 检查 key 是否在字典中
    • items() 返回一个含由 (key, value) 格式元组构成的列表
    • keys() 返回由键构成列表
    • values() 返回由值构成的列表
    • setdefault(key, default) 为键 key 添加默认值 default
    • pop(key) 删除 key 并返回对应的值
  • 集合

    • add(x) 向集合中添加元素 x
    • clear() 清空集合
    • copy() 返回集合的一个复制
    • difference(set) 返回集合与另一个集合的差集
    • discard(x) 删除元素 x
    • isdisjoint(set) 判断两个集合是否有交集
    • issubset(set) 判断新集合 set 是否是集合的子集
    • issuperset() 判断新集合 set 是否是集合的超集

1.3.3.4 重识程序

在某种意义上,我们也可以认为 Python 程序是一个对象,它也有自己的数据和方法。其中 __name__ 就是它的一个变量,我们并没有定义过这个变量,但由于它是程序的对象变量,因此可以直接调用。

__name__
'__main__'

1.3.4 练习

1.3.4.1 重构成绩管理系统

此练习是开放题,使用 面向对象 的编程方法重构之前的成绩管理系统,并完成之前的任务。

Task 1. 在上一次期末考试中,XiaoHu 考了数学 65 分,语文 55 分;XiaoMing 考了数学 80 分,语文92 分;XiaoWei 考了数学 95 分,语文 98 分,以此建立学生成绩管理系统。

Task 2. 在本次期末考试中,XiaoHu 考了数学 95 分,语文 85 分;XiaoMing 考了数学 75 分,语文 71 分;XiaoWei 考了数学 92 分,语文 93 分,以此对之前的成绩进行更新。

Task 3. 由于 XiaoMing 的成绩出现了大幅度下滑,家长决定要 XiaoMing 转学到另一所高中,以此在系统中删除 XiaoMing 的信息。

Task 4. 学校新转来的学生 Cryin 本次考试成绩为 数学 87 分,语文 88 分,在系统中录入 Cryin 的成绩。

class student():def __init__(self, name, Math_score, Chinese_score):self.name = nameself.Math_score = Math_scoreself.Chinese_score = Chinese_score## repr 函数用于定义对象被输出时的输出结果def __repr__(self):return str((self.name, self.Math_score, self.Chinese_score))def change_score(self, course_name, score):if course_name == 'Math':self.Math_score = scoreelif course_name == 'Chinese':self.Chinese_score = scoreelse:print(course_name, " course is still not in current system")def print_name(self,):print(self.name)name = 'Undefined'Math_score = NoneChinese_score = None

之前我们实现了学生类,现在我们通过把学生对象保存在字典中实现一个成绩系统。

## Task1
ab = {}
ab.setdefault('XiaoHu', student('XiaoHu', 65, 55))
ab.setdefault('XiaoMing', student('XiaoMing', 80, 92))
ab.setdefault('XiaoWei', student('XiaoHu', 95, 98))
print(ab)## Task2
ab['XiaoHu'].change_score('Math', 95)
ab['XiaoMing'].change_score('Math', 75)
ab['XiaoWei'].change_score('Math', 92)ab['XiaoHu'].change_score('Chinese', 85)
ab['XiaoMing'].change_score('Chinese', 71)
ab['XiaoWei'].change_score('Chinese', 93)
print(ab)## Task3
ab.pop('XiaoMing')
print(ab)## Task4
ab.setdefault('Cryin', student('Cryin', 87, 88))
print(ab)
{'XiaoHu': ('XiaoHu', 65, 55), 'XiaoMing': ('XiaoMing', 80, 92), 'XiaoWei': ('XiaoHu', 95, 98)}
{'XiaoHu': ('XiaoHu', 95, 85), 'XiaoMing': ('XiaoMing', 75, 71), 'XiaoWei': ('XiaoHu', 92, 93)}
{'XiaoHu': ('XiaoHu', 95, 85), 'XiaoWei': ('XiaoHu', 92, 93)}
{'XiaoHu': ('XiaoHu', 95, 85), 'XiaoWei': ('XiaoHu', 92, 93), 'Cryin': ('Cryin', 87, 88)}

3. Python 面向对象编程相关推荐

  1. 这可能是Python面向对象编程的最佳实践

    作者 | 崔庆才 来源 | 进击的Coder(ID:FightingCoder) Python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了 ...

  2. Python面向对象编程:类继承和其衍生术语

    Python面向对象编程03:类继承和其衍生术语 前面我们讲到过正则表达式字符等,上一篇分享了面向对象编程和类的结构,最后稍微提到了继承. Python面向对象编程:深度认识类class_ Pytho ...

  3. 《Python面向对象编程指南》——1.2 基类中的__init__()方法

    本节书摘来自异步社区<Python面向对象编程指南>一书中的第1章,第1.2节,作者[美]Steven F. Lott, 张心韬 兰亮 译,更多章节内容可以访问云栖社区"异步社区 ...

  4. 关于python面向对象编程中、下列说法中_关于Python面向对象编程的知识点总结

    前言 如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程. 接下来我们 ...

  5. python对象编程例子-这是我见过最详细的Python面向对象编程!建议收藏!

    原标题:这是我见过最详细的Python面向对象编程!建议收藏! 面向对象编程和函数式编程(面向过程编程)都是程序设计的方法,不过稍有区别. 面向过程编程: 1. 导入各种外部库 2. 设计各种全局变量 ...

  6. python面向对象编程的优点-Python面向对象编程——总结面向对象的优点

    Python面向对象编程--总结面向对象的优点 一.从代码级别看面向对象 1.在没有学习类这个概念时,数据与功能是分离的 def exc1(host,port,db,charset): conn=co ...

  7. python编程基础是什么-Python面向对象编程基础解析(一)

    1.什么是面向对象 面向对象(oop)是一种抽象的方法来理解这个世界,世间万物都可以抽象成一个对象,一切事物都是由对象构成的.应用在编程中,是一种开发程序的方法,它将对象作为程序的基本单元. 2.面向 ...

  8. 【Python基础】Python 面向对象编程(上篇)

    我的施工计划图 已完成专题包括: 1我的施工计划 2数字专题 3字符串专题 4列表专题 5流程控制专题 6编程风格专题 7函数使用专题 今天是面向对象编程的上篇:基础专题 Python 面向对象编程 ...

  9. Python 面向对象编程基础

    Python面向对象编程 简介:面向对象编程--Object Oriented Programming,简称 OOP,是一种程序设计思想.OOP 把对象作为程序的基本单元,一个对象包含了数据和操作数据 ...

  10. python面向对象编程138讲_Python面向对象编程简单讲解

    学习目标: 1-面向对象编程 2-类和对象 3-对象的属性和方法 4-类的特性 Python面向对象编程 一种编程程序的设计思想,把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数.把计算机 ...

最新文章

  1. 我的Objective-C系列文章
  2. Android利用Volley异步加载(JSON和图片)完整示例
  3. tracker服务器列表2020_个人服务器采购整理分享
  4. 多元线性回归数据集_TensorFlow学习Program1——13.实现一元、多元线性回归(基于房价数据集)...
  5. Lenovo System x3650 M5 使用ServerGuide安装win2016(U盘安装)
  6. 你的计算机没有安装cad2006,CAD2006安装常见问题及处理方法
  7. 史上最新最全的ADB命令行
  8. 美通企业日报 | 英特尔与阿里云签署战略合作备忘录;赛默飞在苏州扩建临床试验工厂...
  9. 2021年京东最新炸年兽活动用脚本会怎样?JD炸年兽活动参与教程
  10. 大数据毕设选题 - 机器学习餐厅销量预测(大数据 python)
  11. 【neon加速拆分/合并交叉数据】使用neon intrinsics加速合并/拆分uv的内存分布(交叉存储/分别存储)
  12. 建模:蒙特卡洛法求多重积分
  13. 虚拟化及vmware产品介绍
  14. Java能自学吗?如何自学?(附Java学习路线图)
  15. 速卖通买家号怎么注册?
  16. 朋友没有邀请码,也成功让我使用了Club House
  17. w10 恢复 已清空回收站的文件
  18. 赵聪慧 java,基于Instrumentation的JAVA代码暖替换
  19. AXI 总线协议学习笔记(3)
  20. PL/SQL 11g R2 —— 包

热门文章

  1. html5 mac os 开发工具,如何通过TextMate或命令行在Mac OS上使用W3C tidy-html5软件包?...
  2. 计算机专业试讲10分钟教案,10分钟试讲教案怎么写
  3. PAJ7620手势传感器快速应用- -基于涂鸦CBU模组开发板
  4. 【浏览器工作原理与实践笔记一】:宏观视角上的浏览器
  5. Android studio获取服务器端json数据并解析
  6. MathType中输入矩阵转置符号(向下丁字符号 Down tack,形状类似大写字母T)
  7. python编译 pyd 工具_avalon-fsn首页、文档和下载 - Python 编译构造工具 - OSCHINA - 中文开源技术交流社区...
  8. 网上下载的avi格式视频,没有画面怎么办?
  9. Java输入输出数据流
  10. 堡垒机jumpserver 搭建与使用