第1章 Day7
1.1 面向对象与类
面向过程:核心是过程二字,过程指的是问题的解决步骤,即先干什么再干什么,基于
面向过程去设计程序就好比在设计一条流水线,是一种机械式的思维方式
优点:复杂的问题流程化,进而简单化
缺点:可扩展性差
应用:脚本程序,比如linux系统管理脚本,著名案例:linux内核,httpd,git
面向对象:核心是对象二字,对象就是特征与技能的结合体,如果把设计程序比喻成
创造一个世界,那你就是这个世界的上帝,与面向过程对机械流水的模拟形式鲜明的对比
面向对象更加注重的对现实时间的模拟。
优点:可扩展性
缺点:
类即种类,类别,对象是特征和与技能的结合体,那么类就是一系列对象相似的
特征与技能的结合体
在现实世界中:先有一个个具体存在的对象----》(总结相似之处)---》现实中的类
在程序中:一定是先定义类,后调用类来产生对象
#第一阶段:现实中的对象----》现实中类
obj1:
特征
学校=oldboy
名字=李大炮
年龄=18
性别=女
技能
学习
吃饭
obj2:
特征
学校=oldboy
名字=张全蛋
年龄=28
性别=男
技能
学习
吃饭
obj3:
特征
学校=oldboy
名字=牛榴弹
年龄=18
性别=女
技能
学习
吃饭
现实中的老男孩学生类:
相似的特征
学校=oldboy
相似的技能
学习
吃饭
#第二阶段:程序中的类----》程序中的对象
'''
class OldboyStudent:
school = 'oldboy' #类的数据属性
def learn(self): #类的函数属性
print('is learning')
def eat(self):
print('is eating')
print('======>')
#类体的代码在类定义阶段就会执行,理所应当会产生类的名称空间,用__dict__属性查看
# print(OldboyStudent.__dict__)
# print(OldboyStudent.__dict__['school'])
# print(OldboyStudent.__dict__['learn'])
OldboyStudent.__dict__['learn'](123) # 必须传入一个参数 要遵循调用函数的规则
print(OldboyStudent.school)
print(OldboyStudent.learn)
OldboyStudent.x=11111111111111
OldboyStudent.school='oldgril'
print(OldboyStudent.__dict__)
# OldboyStudent.__dict__['x']=222222 # 在python3 类不可以通过__dict__的方式来修改属性(只能查看)只能通过点 . 类调用点的方法来修改 但是在python2中可以
OldboyStudent.x=3333333333333
'''
1.1.1 属性查找
school='hahahahahahaah'
class OldboyStudent:
school = 'oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def learn(self):
print('%s is learning' %self.name)
def eat(self):
print('is eating')
obj1=OldboyStudent('李大炮',18,'女')
# 分两步:
# 第一步:先产生一个空对象obj1
# 第二步:OldboyStudent.__init__(obj1,'李大炮',18,'女')
# print(obj1.__dict__)
obj2=OldboyStudent('张全蛋',28,'男')
obj3=OldboyStudent('牛榴弹',18,'女')
print(obj1.__dict__)
print(obj1.name,obj1.age,obj1.sex)
#对象可以访问类的数据属性,结论:类的数据属性共享给所有对象使用,id对一样
print(obj1.school,id(obj1.school))
print(obj2.school,id(obj2.school))
print(obj3.school,id(obj3.school))
print(OldboyStudent.school,id(OldboyStudent.school))
# 类的函数属性
OldboyStudent.learn(obj1)
OldboyStudent.learn(obj2)
OldboyStudent.learn(obj3)
print(obj1.learn)
print(obj2.learn)
print(obj2.learn)
print(OldboyStudent.learn)
#绑定方法:绑定给谁,就是给谁调用,谁来调用 就把·谁·本身当成第一个参数传入
obj1.learn()#OldboyStudent.learn(obj1)
obj2.learn()#OldboyStudent.learn(obj2)
obj3.learn()#OldboyStudent.learn(obj3)
# 在python3中类型就类
# print(OldboyStudent)
# print(list)
#
# l1=list()
# l2=list()
# l3=list()
# print(l1,type(l1))
# list.append(l1,3)
# l1.append(3)
# print(l1)
# print(l2)
# print(l3)
# print(obj1.__dict__)
1.1.2
属性的查找顺序 :先从对象的__dict__中找,然后到类的__dict__中找,然后 父类
OldboyStudent.school='哈弗'
obj1.school='hahahha'
print(obj1.school)
print(obj2.school)
print(obj3.school)
#
# 统计类的实例化次数,也就是对象的个数
# class Foo:
# count=0
# def __init__(self,x,y,z):
# self.x=x
# self.y=y
# self.z=z
# Foo.count+=1
# obj1=Foo(1,2,3)
# obj2=Foo(1,3,1)
# obj3=Foo(1,1,2)
# print(obj1.count)
# print(Foo.count)
class OldboyStudent:
# school
= 'oldboy'
def
__init__(self,name,age,sex='male'):
self.name=name
self.age=age
self.sex=sex
def learn(self):
print('%s is learning' %self.name)
def eat(self):
print('is eating ')
obj1=OldboyStudent('李大炮',18)
OldboyStudent.eat(1)
# obj1.eat(1)
obj1.learn()
#类里面定义的函数是给对象用的 对象调用这些函数时会把自己的名字当成第一个参数传入 ; 类也可以调用这些函数,但是不会把类名当成第一个参数传入 需要自己指定一个参数(可以是对象名,也可以是其他的名字)
1.1.3 对象之间的交互
class Garen:
camp='Demacia'
def __init__(self,name,life_value=100,aggressivity=80):
self.name=name
self.life_value=life_value
self.aggressivity=aggressivity
def attack(self,enemy):
enemy.life_value-=self.aggressivity
class Riven:
camp='Noxus'
def __init__(self,name,life_value=100,aggressivity=30):
self.name=name
self.life_value=life_value
self.aggressivity=aggressivity
def attack(self,enemy):
enemy.life_value-=self.aggressivity
g1=Garen('草丛猥琐男')
r1=Riven('兔女郎')
print(r1.life_value)
g1.attack(r1)
print(r1.life_value)
但是生成两个对象的类有许多重复代码 能不能精简
1.2 继承
继承的基本形式
class ParentClass1(object): #定义父类
pass
class ParentClass2: #定义父类
pass
class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
pass
class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
pass
#
# print(SubClass1.__bases__)
# print(SubClass2.__bases__)
# print(ParentClass1.__bases__)
# 经典类 是没有继承object 以及该类的子类
#
# 新式类 继承了object 的类 以及该类的子类 python3都是新式类
#经典类与新式类的区别
# #类的继承与派生 继承:完全继承 派生 :指名道姓调用(来继承) 再加上自己的特点
# class Animal:
# x=1
# def __init__(self,name,age,sex):
# self.name=name
# self.age=age
# self.sex=sex
# # print('=====>')
# def eat(self):
# print('%s eat' %self.name)
#
# def talk(self):
# print('%s say' %self.name)
#
# class People(Animal):
# x=10
# def __init__(self,name,age,sex,education):
# Animal.__init__(self,name,age,sex)#指明道姓的调用
# self.education=education
# #print(People.__init__)
# def talk(self):
# Animal.talk(self)#指明道姓的调用 来继承
# print('这是人在说话')
#
#
# class Dog(Animal):
# pass
# class Pig(Animal):
# pass
#
#
#
#
# peo1=People('alex','18','female','小学肄业')
# dog1=Dog('yuanhao',28,'male')
# pig1=Pig('wupeiqi',18,'male')
# print(peo1.education)
# print(peo1.__dict__)
# print(peo1.name)
# # print(dog1.name)
# # print(pig1.name)
#
# peo1.talk()
# print(peo1.x)
class OldboyPeople:
school = 'oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def eat(self):
print('%s is eating' %self.name)
class OldboyStudent(OldboyPeople):
def learn(self):
print('%s is learning' %self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,salary,title):
OldboyPeople.__init__(self,name,age,sex)
self.salary=salary
self.title=title
def teach(self):
print('%s is teaching' %self.name)
yl_obj=OldboyStudent('yanglei',28,'female')
egon_obj=OldboyTeacher('egon',18,'male',3.1,'沙河霸道金牌讲师')
yl_obj.learn()
yl_obj.eat()
print(egon_obj.__dict__)
egon_obj.teach()
'''
总结:
1 继承的功能之一:解决类与类之间的代码重复问题
2 继承是类与类之间的关系,是一种,什么是什么的关系
3 在子类派生出的新的属性,已自己的为准
4 在子类派生出的新的方法内重用父类的功能的方式:指名道姓法
OldboyPeople.__init__
这种调用方式本身与继承是没有关系
'''
1.3 组合
一个对象的属性来自于多个类实例化后的结果
解决代码重用问题
解决了课程 都在老师类 跟学生类的重复设置 单独定义一个类
老师类的属性来自于 父类OldboyPeople 课程类 学生类 共同实例化后的结果
class OldboyPeople:
school = 'oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def eat(self):
print('is eating')
class OldboyStudent(OldboyPeople):
def __init__(self,name,age,sex):
OldboyPeople.__init__(self,name,age,sex)
self.course=[]
def learn(self):
print('%s is learning' %self.name)
def tell_info(self):
print('<name:%s age:%s sex:%s>' %(self.name,self.age,self.sex))
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,salary,title):
OldboyPeople.__init__(self,name,age,sex)
self.salary=salary
self.title=title
self.students=[]
self.course=[]
def teach(self):
print('%s is teaching' %self.name)
class Course:
def __init__(self,course_name,course_period,course_price):
self.course_name=course_name
self.course_period=course_period
self.course_price=course_price
def tell_info(self):
print('<课程名:%s 周期:%s 价格:%s>' %(self.course_name,self.course_period,self.course_price))
python=Course('Python','6mons',3000)
linux=Course('Lnux','3mons',2000)
bigdata=Course('BigData','1mons',1000)
# python.tell_info()
s1 = OldboyStudent('yanglei', 18, 'female')
s2 = OldboyStudent('lilei', 18, 'male')
s3 = OldboyStudent('liulei', 16, 'female')
s4 = OldboyStudent('zhanglei', 17, 'female')
egon_obj=OldboyTeacher('egon',18,'male',3.1,'沙河霸道金牌讲师')
egon_obj.students.append(s1)
egon_obj.students.append(s2)
egon_obj.students.append(s3)
egon_obj.students.append(s4)
for obj in egon_obj.students:
obj.tell_info()
# egon_obj.course.append(python)
# egon_obj.course.append(linux)
#
# for obj in egon_obj.course:
# obj.tell_info()
yl_obj=OldboyStudent('yanglei',28,'female')
yl_obj.course.append(python)
yl_obj.course.append(linux)
yl_obj.course.append(bigdata)
for i in yl_obj.course:
# print(i.course_name,i.course_period,i.course_price)
i.tell_info()
1.4 继承实现原理
#coding:utf-8
#单继承
# class A:
# def f1(self):
# print('A.f1')
#
# def f2(self):
# print('A.f2')
# self.f1() #b.f1()
#
# class B(A):
# def f1(self):
# print('B.f2')
#
#
# b=B()
# # b.f2=111111
# b.f2()
#多继承
class J:
def test(self):
print('J')
class A(J):
# def test(self):
# print('A')
pass
class E(J):
def test(self):
print('E')
pass
class H(J):
def test(self):
print('H')
class G(H):
def test(self):
print('G')
pass
class B(A):
# def test(self):
# print('B')
pass
class D(E):
def test(self):
print('D')
pass
class F(G):
def test(self):
print('F')
pass
class C(B,D,F):
# def test(self):
# print('C')
pass
c=C()
# c.test=1111
# c.test()
#MRO列表
print(C.mro())
#C B A D E F G H J object
python2中经典类 是先纵项后横向
对象调用方法顺序
先从对象的__dict__中找 在从对象的类中找 在从自己类的父类中找 再从父类的父类中找
Python3 新式类 先横向后收口
1.5 子类中调父类的方法
1,指明道姓调用 需要 self
2,Super 不需要指明道姓 不需要 self
一个函数是一个对象的绑定方法 这个对象调用这个方法时会把自己当成第一个参数传入这个函数
super() 调用按照mro列表去调用
super() 就是父类的一个对象调用时会自动把自己当成第一个参数穿进去 调用时不用写self
class OldboyPeople:
school = 'oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def eat(self):
print('is eating')
def teach(self):
print('这是父类的teach')
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,salary,title):
# OldboyPeople.__init__(self,name,age,sex)
#在Python2中需要写全:super(OldboyTeacher,self)
super().__init__(name,age,sex)
self.salary=salary
self.title=title
def teach(self):
# OldboyPeople.teach(self)
super().teach()
print('%s is teaching' %self.name)
print(OldboyTeacher.mro())
egon_obj=OldboyTeacher('egon',18,'male',3.1,'沙河霸道金牌讲师')
# print(egon_obj.title)
# print(egon_obj.__dict__)
egon_obj.teach()
#
# class A:
# def test(self):
# super().test()
# class B:
# def test(self):
# print('B')
#
# class C(A,B):
# pass
#
# # a=A()
# # a.test()
#
# print(C.mro())
# c=C()
# c.test()
1.6 绑定方法与非绑定方法
#绑定给谁就是给谁用 非绑定方法 不与类绑定 也不与对象绑定
# import settings
#
# class MySql:
# def __init__(self,host,port):
# self.host=host
# self.port=port
#
# @classmethod
# def from_conf(cls):
# print(cls)
# # return cls(settings.HOST,settings.PORT)
#
# def func1(self):pass
#
#
# conn1=MySql('127.0.0.1',3306)
# print(MySql.from_conf)
# conn2=MySql.from_conf()
# print(conn1.host,conn2.host)
# print(conn1.func1)
# print(conn1.from_conf)
# print(MySql.from_conf)
# conn1.from_conf()
# MySql.from_conf()
import settings
import uuid
class MySql:
def __init__(self,host,port):
self.host=host
self.port=port
self.id=self.create_id()
# @classmethod
# def from_conf(cls): #绑定给类的
# print(cls)
# # return cls(settings.HOST,settings.PORT)
#
# def func1(self): #绑定给对象的
# pass
@staticmethod #不与任何绑定 谁也可以调用 不会有默认自动传参
def create_id(): #非绑定方法
return str(uuid.uuid1())
conn1=MySql('127.0.0.1',3306)
conn2=MySql('127.0.0.2',3306)
conn3=MySql('127.0.0.3',3306)
# print(MySql.create_id)
# print(conn1.create_id)
print(conn1.id,conn2.id,conn3.id)