组合&反射&面向对象内置函数
内容概要
- 组合
- 反射
- 面向对象的内置函数
- 异常
内容详细
一、组合
组合:在对象中定义一个属性,属性的值是另一个对象
除了继承父类的方法,这是获取另一个类中属性的另一种方式
如果想给学生对象添加课程属性:
1、直接把课程信息在调用阶段传入的话所需要的实参太多了,而且学生对象多需要不断重复传入
2、把课程信息放在People类里面的__init__初始化会给人的类添加了不属于它的课程属性
3、创建课程类,直接把课程类当作Student类的父类,不符合类的特性:学生不是课程类
所以解决以上方法,可以直接产生一个个课程对象,再把课程对象作为学生对象的值传给学生对象,这种方法就是组合
class People:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Course:
def __init__(self, name, period, price):
self.name = name
self.period = period
self.price = price
# 产生课程对象
python = Course('python', '6mon', 20000)
Linux = Course('Linux', '5mon', 10000)
class Student(People):
def __init__(self, name, age, gender, course=None):
if not course:
course = []
super().__init__(name, age, gender)
self.courses = course
# 定义添加课程的方法
def choose_course(self, course):
self.courses.append(course)
# 产生学生对象
stu = Student('elijah', 18, 'male')
# 把课程对象当作属性添加到学生对象的课程列表中
stu.choose_course(python)
stu.choose_course(Linux)
# 这样就可以通过列表中的课程对象去获取相应的课程信息了
print(stu.courses[0].name) # python
print(stu.courses[0].period) # 6mon
print(stu.courses[0].price) # 20000
二、反射
1、getattr
获取对象中的属性值或者方法名,没有属性可以添加第三个参数返回None值
第一个参数是对象名,第二个参数是属性名或者方法名(用字符串的格式)
stu.name
print(getattr(stu, 'name', None))
# 获取方法加括号可以直接调用
stu.func()
getattr(stu, 'choose_course')('linux')
2、setattr
给对象增加属性,第三个参数是属性的值
stu,course = 'math'
setattr(stu, 'course', 'math')
3、hasattr
判断对象中是否有该属性,返回True或者False
hasattr(stu, 'name1')
4、delattr
删除对象中的属性
delattr(stu, 'name')
print(stu.__dict__)
三、内置方法
1、__init__
调用类会自动启动,用于初始化对象
class People:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
2、__str__
打印对象的时候会自动调用,而且该方法要有return返回值,返回值只能是字符串
# 在python中万物皆对象,可以尝试打印一些数据类型赋值的变量或者文件,会出现一连串输出格式,其实就是出发了__str__,早已经定好输出的格式
f = open('a.txt', 'w')
print(f) # <_io.TextIOWrapper name='a.txt' mode='w' encoding='cp936'>
class People:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def __str__(self):
return 'name: %s' % self.name
p = People('elijah', 18, 'male')
print(p) # print(p.__str__())
3、__del__
# 1、删除属性时会自动触发(手动执行)
# 2、程序执行完毕会触发
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __del__(self):
print('__del__')
p = People('elijah', 18)
# del p
print('end====>')
# 结果:先执行了__del__再执行了end===>, 说明在执行del的时候会触发__del__方法
# __del__
# end====>
# 把del 删除操作注释掉: __del__在程序结束之后会执行
# end====>
# __del__
作用:在程序中如果进行了文件打开操作open(),会占用系统资源且不会自动关闭,所以在程序运行结束之后可以在__del__方法下执行f.close()操作,把文件接口关闭
4、__enter__ 与 __exit__ (with语句中被触发)
上下文管理,出现with语句,对象的__enter__方法会被触发,有返回值则赋值给as声明的变量
with中程序结束后会执行__exit__方法
class Open():
def __init__(self, name):
self.name = name
def __enter__(self):
print('with程序运行前执行')
def __exit__(self):
# 在with语句执行完成后会运行__exit__方法,可以在__exit__方法中关闭文件
f.close()
print('with程序运行后执行')
with Open('a.txt') as f
5、__call__
# 对象加括号自动触发
def __call__(self, *args, **kwargs):
print('__call__')
stu()
四、异常
1. 什么是异常?
程序如果存在逻辑错误或者语法错误,在执行的时候会报出错误信号,并停止运行,异常之后的代码都不会执行
异常的种类:
1. 语法错误
print(123
2. 逻辑错误
# 逻辑错误尽量写到完美
a = [1, 2, 3]
a[5]
2、 异常三个重要组成部分
1.traceback
翻到最下面从下往上的第一个蓝色字体鼠标左键点击即可跳转到错误的代码所在的行
2.XXXError
错误的类型
3.错误类型冒号后面的内容
错误的详细原因(很重要 仔细看完之后可能就会找到解决的方法)
3、异常处理
把有可能出错的代码放进异常处理的代码里,出错时会接收错误信息并可返回,继续执行剩余的代码
4、异常处理使用注意
1、尽量只在有可能出错的代码段才使用
2、异常处理中的代码越少越好
3、异常处理的频率越低越好
try:
被监测代码
except 异常的类型:
pass
except 异常的类型:
pass
except 异常的类型:
pass
except Exception as e:
pass
else:
# 当被监测代码没有发生异常的时候,触发的
pass
finally:
不管被监测的代码有没有出错,都执行

浙公网安备 33010602011771号