table of Contents
Combination, polymorphism and polymorphism, encapsulation
A combination of
1.1 What is a combination
Is a property of the object is an object of another class
1.2 The concept of combination
class Foo:
def __init__(self,bar):
self.bar = bar
class Bar:
pass
f = Foo()
f.bar = Bar() # 这就是对象f的属性bar是类Bar的对象
1.3 Why use a combination of
You can reduce code redundancy
# 没有用组合的时候,选课系统,需要写人的类,老师的类,学生的类,老师类中又需要姓名、年龄、等级、课程名、课程价格、课程周期等属性;学生类中需要姓名、年龄、课程、课程名、课程价格、课程周期等属性,这时候写起来代码会很复杂而且有重复
class Person:
school = 'oldboy'
class Teacher(Person):
def __init__(self,name,age,level,course_name,course_parice,course_period):
self.name = name
self.age = age
self.level = level
self.course_name = course_name
self.course_price = course_price
self.course_period = course_period
class Student(Person):
def __init__(self,name,age,course_name,course_price,course_period):
self.name = name
self.age = age
self.course_name = course_name
self.course_price = course_price
self.course_period = course_period
# 上述代码就很繁琐,下面通过组合解决代码冗余
class Person:
school = 'oldboy'
class Teacher(Person):
def __init__(self,name,age,level,course):
self.name = name
self.age = age
self.level = level
self.course = course # course 是课程对象,表示老师教授的课程
class Student(Person):
def __init__(self,name,age,course):
self.name = name
self.age = age
self.course = course
class Course: # 把课程名称、价格、周期这些属性放到Course的类中
def __init__(self,course_name,course_price,course_period):
self.course_name = course_name
self.course_price = course_price
self.course_period = course_period
course = Course('python',21800,7)
stu = Student('zyl',19,course)
teacher = Teacher('nick',22,'高级',course)
print(teacher.course.name) # 查看老师教授的课程名字
# 进阶版
class Person:
school = 'oldboy'
class Teacher(Person):
def __init__(self,name,age,level,course):
self.name = name
self.age = age
self.level = level
# course是课程对象,表示老师教授的课程
self.course = course
class Student(Person):
def __init__(self, name, age):
self.name = name
self.age = age
#course是课程对象,表示老师教授的课程
self.course_list = [] #定义一个课程列表的空列表
def choose_course(self, course): # 定义一个选择课程的方法
# 把课程对象追加到学生选课的列表中
self.course_list.append(course)
def tell_all_course(self): # 定义一个选择课程的方法
# 循环学生选课列表,每次拿出一个课程对象
for course in self.course_list:
# 课程对象.name 取到课程名字
print(course.course_name)
class Course: #定义一个课程类
def __init__(self,course_name, course_price, course_time):
self.course_name = course_name
self.course_price = course_price
self.course_time = course_time
#产生对象
course = Course('python','20000',7) #把课程的参数传进去
stu1 = Student('jiayi',18)
stu1.choose_course(course) #输出学生1的课程选择
stu2 = Student('ypp',18)
stu2.choose_course(course)
stu2.choose_course(Course('Linux',20000,7))
# 查看stu2选的所有课程名称
#方式一(通过对象的绑定方法)
stu2.tell_all_course()
#方式二(通过普通函数)
def tell_all_course(student):
for course in student.course_list: #循环课程里面的对象
print(course.course_name) #输出课程姓名
tell_all_course(stu2)
1.4 inheritance and composition, respectively, at what time with
1. inherited way
By inheritance to establish a relationship between the derived class and the base class, it is a 'yes' relationship, such as the white horse is a horse, man is an animal.
When there between classes many of the same features, extract these common features make the base class, inheritance is better, such as the teacher is a person, who is a student
2. The combination of the way
In combination with the established relationship between class and class combination, it is a 'have' relationships, such as birthday professors, and professors teach python linux courses on student s1, s2, s3 ...
When significantly different between the classes, and the smaller is the component of a larger class of the class required, in combination with better
Second, polymorphism and polymorphism
2.1 What is a multi-state
Various forms of a class of things (different forms of the same class of things) eg: ice water, water vapor. Animals are pigs, dogs, people
class Animal: #定义一个动物类
def speak(self): #定义一个speak的方法
pass
class Pig(Animal):
def speak(self): #pig会speak
print('哼哼哼')
class Dog(Animal):
def speak(self): #Dog会speak
print('汪汪')
class People(Animal):
def speak(self): #people会speak
print('say hello')
"""产生对象"""
pig=Pig()
dog=Dog()
people=People()
"""调用方法"""
pig.speak()
dog.speak()
people.speak()
2.2 How polymorphism
- Method a: a unified interface to implement abc, the code constraint (with less)
import abc
#第一在括号中写metaclass=abc.ABCMeta
class Animal(metaclass=abc.ABCMeta):
#第二在要约束的方法上,写abc.abstractmethod装饰器
@abc.abstractmethod
def speak(self):
pass
class Pig(Animal):
def speak(self): #此时必须用speak,其他变量名都不行,因为做了约束
print('哼哼哼')
class Dog(Animal):
def speak(self): #此时必须用speak,其他变量名都不行,因为做了
print('汪汪')
class People(Animal):
def speak(self): #此时必须用speak,其他变量名都不行,因为做了
print('say hello')
#产生对象
pig = Pig() #方式一
pig.speak() #这样我们就可以获取'哼哼哼'
#定义了一个函数,但是没有利用到多态性
def animal_speak(obj): #定义函数 #方式二
obj.speak()
pig = Pig() #产生对象
animal_speak(pig)
-------------------------------------------------
哼哼哼
- Method 2: exception handling implement (common)
class Animal():
def speak(self):
#主动抛出异常
raise Exception('你得给我重写它啊,我已经做了代码约束')
class Pig(Animal):
#此时必须用speak,其他变量名都不行,因为做了约束
#代码运行时抛出了异常,所以必须把不一样的变量名改过来
def speak(self):
print('哼哼哼')
class People(Animal):
def speak(self):
print('say hello')
pig=Pig()
pe=People()
def animal_speak(obj):
obj.speak()
animal_speak(pig)
animal_speak(pe)
- Method three: advocating duck type. As long walks like a duck (object has a binding method), then you are a duck
class Pig:
def speak(self): #只要是speak变量名,就把他看成多态
print('哼哼哼')
class People:
def speak(self): #只要是speak变量名,就把他看成多态
print('say hello')
pig=Pig()
pe=People()
def animal_speak(obj):
obj.speak()
animal_speak(pig)
animal_speak(pe)
2.3 What is polymorphism
Everything has the same characteristics of a class, but not the same characteristics
eg: animal will speak, but people speak is 'say hello', but the pig speak is 'hum hum'.
2.4 Benefits polymorphism
- Increase the flexibility of the program
- Increase the scalability of the program (if again a giraffe, it will speak, we will also use
self.speak = speak
)
Third, the package
3.1 What is the package
Hidden object properties and methods, just outside the provision of public access, that is to say that we have a sack, kitten, puppy, little bastard are fitted to the inside sacks.
3.2 How to package
- Packing things into it, not hide access
3.3 How to achieve encapsulation Code
Hidden attributes : by __变量名
hiding property, not hiding behind external access, only able to access the internal
#封装name属性
class Person:
def __init__(self,name,age):
self.__name = name #封装name属性
self.age = age
def get_name(self):
return self.__name #只能拿不能改
#产生对象
p = Person('jiayi',20)
# 查看属性
print(p.age) #20
# print(p.__name) #报错,获取不到
print(p.get_name()) #可以获取到
# 获取name属性(隐藏的属性访问不到?实际上有方法能访问到)
print(p._Person__name) #通过'_父类__属性'获取
print(p.__dict__) #获取对象的所有属性,会打印出来
Purpose: To improve the security against being modified
Concealment methods : by __方法名
hiding method, after less than a hidden external access, only able to access the internal
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
def __speak(self): #隐藏speak方法
print('6666')
p=Person('nick',89) #产生对象,并传值
p.__speak() #获取speak方法,报错
print(Person.__dict__) #获取Person的所有属性
# 获取speak方法(隐藏的属性访问不到?实际上有方法能访问到)
p._Person__speak() #获取speak方法
Objective: To isolate complexity eg: shoot camera
3.4 property decorator
# 计算人的bmi指数
# property装饰器:把方法包装成数据属性
class Person:
def __init__(self,name,height,weight):
self.name=name
self.height=height
self.weight=weight
@property
def bmi(self):
return self.weight/(self.height**2)
# return self.weight/(self.height*self.height)
p=Person('yjy',1.73,57)
# print(p.bmi())
print(p.bmi)
3.5 Packaging and scalability
# property之setter和deleter
class Person:
def __init__(self,name,height,weight):
self.__name=name
self.__height=height
self.__weight=weight
@property
def name(self):
return '[我的名字是:%s]'%self.__name
#用property装饰的方法名.setter
@name.setter
def name(self,new_name):
# if not isinstance(new_name,str):
if type(new_name) is not str:
raise Exception('改不了')
if new_name.startswith('sb'):
raise Exception('不能以sb开头')
self.__name=new_name
# 用property装饰的方法名.deleter
@name.deleter
def name(self):
# raise Exception('不能删')
print('删除成功') #手动写进去的打印,骗客户的
# del self.__name
p=Person('yjy',1.73,57)
# print(p.name)
# p.name='pppp'
# p.name='xxx'
#改不了,直接抛一异常
# p.name=999 #测试@name.setter
# p.name='sb_nick' #测试@name.deleter
# print(p.name)
del p.name
print(p.name) #会输出删除成功,但是并没有删除成功,是删除不了的
Fourth, the supplement: isinstance built-in method
Determine whether an object is an object of a class, returns True or False
print(isinstance([1,2,],str)) # False
print(type('xxx') is str) # True
#这个不对
print(type('xxx') is 'str') # False