听课笔记,中国大学mooc 《Python语言基础与应用》陈斌
目录
1. 对象
(1)对象的基本概念
对象 = 属性+方法
对象以id作为标识,既包含数据(属性),也包含代码(方法),是某一类具体事务的特殊实例。
对象实现了属性和方法的封装,是一种数据抽象机制。
(2)对象属性和方法的引用
引用形式 <对象名>.<属性名>
python语言动态的特征,使得对象可以随时增加或者删除属性或者方法。
print(f3.fx, f3.fy)
f3.fz = 3.4
print(f3.fz)
del f3.fz
"""
output:
0.0 4.5
3.4
"""
2. 面向对象编程
面向对象编程(OOP)是一种程序设计范型,同时也是一种程序开发方法
程序中包含各种独立而又能互相调用的对象
每个对象都能接受、处理数据并将数据传递给其他对象。
3. 类的定义与调用
(1)类(class)是对象的模板,封装了对应现实实体的性质和行为
(2)实例对象(instance objects)是类的具体化
把类比作模具,对象则是用模具制造出来的零件
(3)类的出现,为面向对象编程的三个最重要的特性提供了实现的手段
封装性、继承性、多态性
封装性:类可以把一些数据一些属性以及方法行为一些代码封装在一起,这样的抽象的层次就更高
继承性:继承性体现在有一些类之间是有关系的,有些类特殊,有些类通用
多态性:多态性就使得面向对象的同一类型的代码或者同一段代码可以处理不同的对象,甚至可以处理不同类型的对象
(4)python中约定,类名用大写字母开头,函数用小写字母开头,以便区分
(5)定义类
class语句
class <类名>:
<一系列方法的调用>
类的初始化
class <类名>:
def __init__(self, <参数表>):
def <方法名> (self, <参数表>):
__init__() 是一个特殊的函数名,用于根据类的定义创建实例对象,第一个参数必须为self
(6)调用类
<类名> (<参数>)
调用类会创建一个对象,(注意括号!)
obj = <类名> (<参数表>)
返回一个对象实例, 类方法中的self指这个对象实例!
使用点(.)操作符来调用对象里的方法
t = turtle.Pen()
t.left(90)
(7)举例
class Force:
def __init__(self, x, y):
self.fx, self.fy = x, y
def show(self):
print("Force<%s,%s>" % (self.fx, self.fy))
def add(self, force2):
x = self.fx + force2.fx
y = self.fy + force2.fy
return Force(x, y) #返回一个新的力的对象
#生成一个力对象
f1 = Force(0, 1)
f1.show()
#生成另一个力对象
f2 = Force(3, 4)
#合成为新的力
f3 = f1.add(f2)
f3.show()
4. 类定义中的特殊方法
在类定义中实现一些特殊方法,可以方便地使用python中的一些内置操作
所有特殊方法的名称以两个下划线(__)开始和结束
(1)构造与解构
对象构造器 __init__(self,[...) 对象的构造器,实例化对象时调用
析构器 __del__(self,[...) 销毁对象时调用
举例:
from os.path import join
class FileObject:
'''给文件对象进行包装从而确认在删除时文件流关闭'''
def __init__(self, filepath = '~', filename = 'sample.txt'):
#读写模式打开一个文件
self.file = open(join(filepath, filename), 'r+')
def __del__(self):
self.file.close()
del self.file
(2)算术操作符
__add__(self, other):
__sub__(self, other):
__mul__(self, other):
__divmod__(self, other):
def __mul__(self, n):
x, y = self.fx * n, self.fy * n
return Force(x,y)
(3)大小比较
__eq__(self, other): #==
__ne__(self, other): #!=
__lt__(self, other): #<
__gt__(self, other): #>
__le__(self, other): #<=
__ge__(self, other): #>=
返回逻辑类型的对象,true,false
(4)字符串操作
__str__(self): #自动转换为字符串
__repr__(self): #返回一个用来表示对象的字符串
__len__(self): #返回元素个数
5. 自定义对象的排序
(1)列表排序
列表方法sort()
对原列表进行排序,改变原列表内容
- 如果列表中的元素都是数字,默认按升序排序,通过添加参数reverse = True可改为降序排列
- 如果元素都是字符串,则会按照字母表顺序排序
通用函数sorted()
类似sort(), 但返回的是排好序的列表副本,原列表内容不变
只有当列表中的所有元素都是同一种类型时,sort()和sorted()才会正常工作
(2)特殊方法 __lt__
由于python的可扩展性,每种数据类型可以定义特殊方法
例: def __lt__(self, y) #返回True视为比y小, self排在前
只要类定义中定义了特殊方法__lt__,任何自定义类都可以使用x<y这样的比较
举例:按照成绩由高到低排序
class Student:
def __init__(self, name, grade):
self.name, self.grade = name, grade
#内置sort函数只引用 < 比较符来判断前后
def __lt__(self, other):
#成绩比other高的,排在他前面
return self.grade > other.grade
#Student的易读字符串表示
def __str__(self):
return "(%s, %d)" % (self.name, self.grade)
#Student 的正式字符串表示,我们让它跟易读表示相同
__repr__ = __str__
s = list()
# 添加Student对象到List中
s.append(Student("Jack", 80))
s.append(Student("Jane", 75))
s.append(Student("Smith", 82))
s.append(Student("Cook", 90))
s.append(Student("Tom", 70))
print("Original:", s)
#对list进行排序,这个sort是列表本身的方法,在比较大小的时候调用了我们Student类的__lt__的特殊方法
s.sort()
print("Sorted:", s)
"""
D:\python.exe D:/test9.py
Original: [(Jack, 80), (Jane, 75), (Smith, 82), (Cook, 90), (Tom, 70)]
Sorted: [(Cook, 90), (Smith, 82), (Jack, 80), (Jane, 75), (Tom, 70)]
Process finished with exit code 0
"""
6. 类的继承
(1)类的继承机制
继承: 如果一个类别A继承自另一个类别B,就把继承者A成为子类,被继承的类B称为父类、基类或超类
代码复用: 利用继承可以从已有类中衍生出新的类,添加或修改部分功能,新类具有旧类中的各种属性和方法,而不需要进行任何复制
举例:
class Car:
def __init__(self, name):
self.name = name
self.remain_mile = 0
def fill_fuel(self, miles): #加燃料里程
self.remain_mile = miles
def run(self, miles): #跑miles英里
print(self.name, end=': ')
if self.remain_mile >= miles:
self.remain_mile -= miles
print(("run %d miles!" % (miles,)))
else:
print("fuel out!")
class GasCar(Car):
def fill_fuel(self, gas): #加汽油gas升
self.remain_mile = gas * 6.0 #每升跑6英里
class ElecCar(Car):
def fill_fuel(self, power): #充电power度
self.remain_mile = power * 3.0 #每度电3英里
具体执行:
gcar = GasCar("BMW")
gcar.fill_fuel(50.0)
gcar.run(200.0)
ecar = ElecCar("Tesla")
ecar.fill_fuel(60.0)
ecar.run(200.0)
'''
BMW: run 200 miles!
Tesla: fuel out!
'''
(2)子类与父类
- 定义:如果两个类具有”一般-特殊“的逻辑关系,那么特殊类就可以作为一般类的”子类“来定义,从”父类“继承属性和方法
class<子类名>(<父类名>):
def <重定义方法>(self, ...):
子类当中不用写任何的代码就自动拥有了父类的所有的方法,也可以定义新的方法,包括可以def一个父类当中没有的方法,也可以定义父类当中已有的方法,相当于覆盖了重新定义
- 覆盖(Override)
子类对象可以调用父类方法,除非这个方法在子类中重新定义了
如果子类同名方法覆盖了父类的方法,仍然还可以调用父类的方法
- 子类还可以添加父类中没有的方法和属性
(3)关于self
在类定义中,所有方法的首个参数一般都是self
self的作用:在类内部,实例化过程中传入的所有数据都赋给这个变量
self实际上代表对象实例
<对象>.<方法>(<参数>)
等价于:
<类>.<方法>(<对象>,<参数>)
举例:
第三行等价于第四行
gcar = GasCar("BMW")
gcar.fill_fuel(50.0)
gcar.run(200.0)
GasCar.run(gcar,200.0)