组合
组合: 就是一个对象拥有一个属性, 该属性的值是另外一个对象
组合的作用: 另一种解决类与类之间的代码冗余问题
为什么要用组合?
因为继承: 是满足什么是什么的关系, is—a的关系
所以继承的使用是有一定的限制的,并且继承是一把双刃剑,并不是继承的越多就越好eg:
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
class Student(People):
def __init__(self, name, age, gender, course=None):
if course is None:
course = []
self.courses = course
super().__init__(name, age, gender, )
'''
学生和老师都需要课程,但是管理员不需要课程,管理员,老师,学生都是人,可以继承People类
因此People类就不能有关于课程的属性,只能重新定义一个新的类Course,显而易见,学生不是课程,
所以不能使用继承的方式去调用,为了减少代码冗余,组合就诞生了
'''
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/be96d63cea3c694ff338b5ac492042bf.png)
怎么使用组合
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):
def __init__(self, name, age, gender, course=None):
if course is None:
course = []
self.course = course
super().__init__(name, age, gender, )
def choose_course(self, course):
self.courses.append(course)
st1 = ('tom', 19, 'male')
st1.choose_course(python)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ab76a5bd32ab8c8be4f02f312adea8ae.png)
面向对象的内置函数
1. __init__()
2. __str__()
3. __del__()
4. __enter__()
5. __exit__()
6. __call__()
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
def __del__(self):
print('__del__')
self.f.close()
def __call__(self, *args, **kwargs):
print('__call__')
stu = Student('ly', 20)
class Open:
def __init__(self, name):
self.name = name
def __enter__(self):
print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
def __exit__(self, exc_type, exc_val, exc_tb):
print('with中代码块执行完毕时执行我啊')
with Open('a.txt') as f:
print('=====>执行代码块')
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a2923e68a6c0c8b53e814933818a64f2.png)
反射
反射就是指对象通过字符串来操作类或者对象的属性
反射本质就是在使用内置函数,其中反射有以下四个内置函数:
1. hasattr:判断一个方法是否存在与这个类中
2. getattr:根据字符串去获取obj对象里的对应的方法的内存地址,加"()"括号即可执行
3. setattr:通过setattr将外部的一个函数绑定到实例中
4. delattr:删除一个实例或者类中的方法和属性
在python中一切皆对象,我们以time类(time模块) 和 People类为例
class People():
school = 'SH'
def __init__(self, name, age, gender, ):
self.name = name
self.age = age
self.gender = gender
print(hasattr(time, 'sleep'))
getattr(time, 'sleep')(1)
1. 设置属性
setattr(People, 'x', 123)
print(People.x)
2. 设置方法(用的很少)
def func():
print('func')
setattr(People, 'print_func', func)
People.print_func(People)
delattr(People, 'school')
print(hasattr(People,'school'))
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/49a41aa89e4bc5f8192cbe8076d66667.png)