组合
组合就是一个对象拥有一个属性,该属性的值是另外一个对象。组合与继承都是用来解决代码的重用性问题。不同的是:继承是一种“是”的关系,比如老师是人、学生是人,当类之间有很多相同之处,应该使用继承;而组合则是一种“有”的关系,比如老师有生日,老师有多门课程,当类之间有显著不同,并且较小的类是较大的类所需要的组件时,应该使用组合
class People(): school = 'SH' def __init__(self, name, age, gender, ): self.name = name self.age = age self.gender = gender class Admin(People): pass class Course(): def __init__(self, name, period, price, ): self.name = name self.period = period self.price = price python = Course('python', '6mon', 10000) linux = Course('linux', '5mon', 20000) class Student(People, Course): def __init__(self, name, age, gender, course=None): if course is None: course = [] self.courses = course super().__init__(name, age, gender, ) def choose_course(self, stu_obj, course): stu_obj.courses.append(course) # stu = Student('ly', 19, 'male', 'python', '6mon', 1000) # print(stu.course_name) stu = Student('ly', 20, 'male') stu.courses.append(python.name) stu.courses.append(linux.name) # ['python','linux'] print(stu.courses) class Teacher(People, Course): def __init__(self, name, age, gender, level): self.level = level super().__init__(name, age, gender, ) def score(self, stu_obj, score): stu_obj.score = score tea = Teacher('ly', 19, 'male', 10) tea.course = linux print(tea.course.name) print(tea.course.price) print(tea.course.period)
面向对象的内置函数
上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法
__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行
出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量,with中代码块执行完毕时执行__exit__
class Student(): school = 'SH' # 调用类的时候触发 def __init__(self, name, age): self.name = name self.age = age def tell(self): print('name: %s, age: %s' % (self.name, self.age)) # 打印对象的时候,自动触发的函数 # 返回值只能是字符串 def __str__(self): return 'name:%s' % self.name return 123 stu = Student('ly', 20) print(stu) # print(stu.__str__()) f = open('a.txt', mode='w') print(f) # __del__ class Student(): school = 'SH' # 调用类的时候触发 def __init__(self, name, age): self.name = name self.age = age self.f = open('a.txt', 'r') # 1. 手动执行del # 2. 程序执行完毕触发 def __del__(self): print('__del__') self.f.close() stu = Student('ly', 19) # del stu.name print('end=>>>>>>>>>>>>') # __enter__ __exit__ class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') # return self return 123 def __exit__(self, exc_type, exc_val, exc_tb): print('with中代码块执行完毕时执行我啊') with Open('a.txt') as f: print('=====>执行代码块') print(f) print(f,f.name) class Foo: def __init__(self): pass # 对象加括号自动触发 def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 执行 __init__ # 一切皆对象 obj() a = list([1, 2, 3]) # a.append(4) # list.append(a, 4) list.append(a, 5) print(a)
反射
反射:通过字符串来操作类或者对象的属性
四个内置函数
1.hasattr() 判断一个对象中是否有某个属性或方法
print(p,'print_name') p是对象,print_name是方法 True或False
2.getattr() 通过字符串获取对象中的属性或方法
print(getattr(p,'print_name')) 函数内存地址
getattr(p,'print_name')() 调用
3.setattr() 通过字符串设置对象的属性或方法
setattr(p,'sex','男') 设置属性
4.delattr() 通过字符串删除对象的属性或方法
delattr(p,'name') 通过反射删除name属性