上节课复习
#1、先定义类 class OldboyStudent: #数据属性 school='oldboy' #函数属性 def choose_course(self): print('is choosing course') #强调:类定义阶段会立刻执行类体代码,会产生类的名称空间,将类体代码执行过程中产生的名字都丢进去 # print(OldboyStudent.__dict__) # 类本质就是一个名称空间/容器,从类的名称空间中增/删/改/查名字 # python为我们提供专门访问属性(名称空间中的名字)的语法,点后的都是属性 # OldboyStudent.school #OldboyStudent.__dict__['school'] # OldboyStudent.x=1 #OldboyStudent.__dict__['x']=1 # OldboyStudent.school='Oldboy' #OldboyStudent.__dict__['school']='Oldboy' # del OldboyStudent.x #del OldboyStudent.__dict__['x'] # 类中定义的函数是类的函数属性,类可以使用,但使用的就是一个普通的函数而已,
意味着需要完全遵循函数的参数规则,该传几个值就传几个
# OldboyStudent.choose_course(123) #2、后调用类产生对象,调用类的过程称之为实例化,实例化的结果称为类的一个实例或者对象 stu1=OldboyStudent() stu2=OldboyStudent() stu3=OldboyStudent() # print(stu1) # print(stu2) # print(stu3) # print(OldboyStudent.school) # OldboyStudent.school='OLDBOY' # print(stu1.school) # print(stu2.school) # print(stu3.school)
对对象定制自己独有的属性
# 例1 class OldboyStudent: school='oldboy' def choose_course(self): print('is choosing course') print(OldboyStudent.__dict__) stu1=OldboyStudent() stu2=OldboyStudent() stu3=OldboyStudent() #对象本质也就是一个名称空间而已,对象名称空间是用存放对象自己独有的名字/属性,而 #类中存放的是对象们共有的属性 print(stu1.__dict__) print(stu2.__dict__) print(stu3.__dict__) stu1.name='耗哥' stu1.age=18 stu1.sex='male' print(stu1.name,stu1.age,stu1.sex) print(stu1.__dict__) stu2.name='猪哥' stu2.age=17 stu2.sex='male' print(stu2.__dict__) stu3.name='帅翔' stu3.age=19 stu3.sex='female' print(stu3.__dict__)
总结:把对象共有的丢类里面放着,对象独有的专门找空间放着,这样更加节省空间了
查找顺序先从自己这里找然后再从类里面找
#不够好,三次调用都不想调用
class OldboyStudent: school='oldboy' def choose_course(self): print('is choosing course') stu1=OldboyStudent() stu2=OldboyStudent() stu3=OldboyStudent() # def init(obj,x,y,z): obj.name=x obj.age=y obj.sex=z # stu1.name='耗哥' # stu1.age=18 # stu1.sex='male' init(stu1,'耗哥',18,'male') # stu2.name='猪哥' # stu2.age=17 # stu2.sex='male' init(stu2,'诸哥',17,'male') # stu3.name='帅翔' # stu3.age=19 # stu3.sex='female' init(stu3,'帅翔',19,'female') print(stu1.__dict__) print(stu2.__dict__) print(stu3.__dict__)
精简版 三次调用都不想调用
class OldboyStudent: school='oldboy' def __init__(obj, x, y, z): #会在调用类时自动触发 obj.name = x #stu1.name='耗哥' obj.age = y #stu1.age=18 obj.sex = z #stu1.sex='male' def choose_course(self): print('is choosing course') #调用类时发生两件事 #1、创造一个空对象stu1 #2、自动触发类中__init__功能的执行,将stu1以及调用类括号内的参数一同传入 stu1=OldboyStudent('耗哥',18,'male') #OldboyStudent.__init__(stu1,'耗哥',18,'male') stu2=OldboyStudent('猪哥',17,'male') stu3=OldboyStudent('帅翔',19,'female')
print(stu1.__dict__)
print(stu2.__dict__)
print(stu3.__dict__)
属性查找
xxx=111 class OldboyStudent: school='oldboy' count=0 def __init__(self, x, y, z): #会在调用类时自动触发 self.name = x #stu1.name='耗哥' self.age = y #stu1.age=18 self.sex = z #stu1.sex='male' #self.count+=1这是对象的属性 OldboyStudent.count+=1#这是类的属性 def choose_course(self): print('is choosing course') # 先从对象自己的名称空间找,没有则去类中找,如果类也没有则报错 stu1=OldboyStudent('耗哥',18,'male') stu2=OldboyStudent('猪哥',17,'male') stu3=OldboyStudent('帅翔',19,'female') print(OldboyStudent.count) print(stu1.count) print(stu2.count) print(stu3.count) # stu1.xxx #会报错 先看自己的,再看类的 类当中的schooll修改所有对象都会修改 #每实例化一次就计数一次
绑定方法
类中定义的数据属性,类共享给对象使用,类中定义的函数是函数属性,类能用,但类在用的时候
只是一个普通函数,该怎么传参就怎么传参。但类中的函数属性是绑定给对象用的(先绑定)
每个对象都有自己单独的内存地址,内存地址指向类中的函数的,所以类中的函数是绑定给对象用的
绑定方法的特点是绑定给谁就应该给谁来调。
class OldboyStudent: school='oldboy' def __init__(self, x, y, z): #会在调用类时自动触发 self.name = x #stu1.name='耗哥' self.age = y #stu1.age=18 self.sex = z #stu1.sex='male' def choose_course(self,x): print('%s is choosing course' %self.name) def func(): pass # 类名称空间中定义的数据属性和函数属性都是共享给所有对象用的 # 对象名称空间中定义的只有数据属性,而且时对象所独有的数据属性 stu1=OldboyStudent('耗哥',18,'male') stu2=OldboyStudent('猪哥',17,'male') stu3=OldboyStudent('帅翔',19,'female') # print(stu1.name) # print(stu1.school) # 类中定义的函数是类的函数属性,类可以使用,但使用的就是一个普通的函数而已,意味着需要完全遵循函数的参数规则,该传几个值就传几个 # print(OldboyStudent.choose_course) # OldboyStudent.choose_course(123) # 类中定义的函数是共享给所有对象的,对象也可以使用,而且是绑定给对象用的, #绑定的效果:绑定给谁,就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入
继承与派生
#初级版 # class oldboypeople:#父类 将oldboystudent和oldboyteacher共有的添加到父类 # school='oldboy' # # class oldboystudent(oldboypeople): # school='oldboy' # # def __init__(self,name,age,sex): # self.name=name # self.age=age # self.sex=sex # # def choose_course(self): # print('%s is choosing course'%self.name) # # class oldboyteacher(oldboypeople): # school='oldboy' # # def __init__(self,name,age,sex,level): # self.name=name # self.age=age # self.sex=sex # self.level=level # def score(self): # print('%s is scoring'%self.name) # # stu1=oldboystudent('豪哥',18,'male') # tea1=oldboyteacher('egon',18,'female',10) # # # 对象查找属性的顺序:对象自己->对象的类->父类-> # print(stu1.school) # print(tea1.school) # #上面的代码没有最终完善还有冗余代码的内容
学生类
class oldboypeople:#父类 将oldboystudent和oldboyteacher共有的添加到父类 school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class oldboystudent(oldboypeople): school='oldboy' def choose_course(self): print('%s is choosing course'%self.name) stu1=oldboystudent('豪哥',18,'male') print(stu1.__dict__)
老师类
class oldboypeople: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class oldboyteacher(oldboypeople): def __init__(self,name,age,sex,level): oldboypeople.__init__(self,name,age,sex) self.level=level #这就是派生 def score(self): print('%s is scoring'%self.name) tea1=oldboyteacher('egon',18,'female',10) print(tea1.__dict__) 在子类派生出新的功能中重用父类的功能的方式有两种: 指名道姓访问某一个类的函数:改方式与继承无关 尽量不要用太多这种方法因为强耦合
老师给学生打分
class oldboypeople: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class oldboystudent(oldboypeople): def __init__(self,name,age,sex,stu_id): oldboypeople.__init__(self,name,age,sex) self.stu_id=stu_id def choose_course(self): print('%s is choosing course'%self.name) class oldboyteacher(oldboypeople): def __init__(self,name,age,sex,level): oldboypeople.__init__(self,name,age,sex) self.level=level def score(self,stu,num): stu.score=num print('老师[%s] 为学生[%s]打分[%s]'%(self.name,stu.name,num)) #stu是学生对象 stu1=oldboystudent('猪哥','19','male',1) tea1=oldboyteacher('egon',18,'male',10) stu1.choose_course() tea1.score(stu1,100) print(stu1.__dict__)
class foo:#父类 def f1(self): print('foo.f1') def f2(self): print('foo.f2') self.f1() class bar(foo): def f1(self): print('bar.f1') 对象查找的顺序:对象自己->对象的类_>父类->父类 obj=bar() obj.f2()
今日作业
1、类的属性和对象的属性有什么区别?
类属性是类和对象共有的,对象属性是只有这个对象独有的。
2、面向过程变成与面向对象编程的区别与应用场景
面向过程程序设计的核心是过程,即解决问题的步骤,先干什么,再干什么。基于该思想编写程序就好比设计一条流水线。 优点:复杂的问题流程化,进而简单化。 缺点:可扩展性差。 应用场景:操作系统一般用面向过程来写 面向对象是利用"类"与"对象"利用各种模型来实现对真实世界的描述。 优点:更容易扩展和修改,更容易理解 缺点:编程的复杂度高可控性差 应用场景:复杂的应用程序一般用面向对象来写
3、类和对象在内存中是如何保存的
以字典的方式保存,代码在类定义阶段便会执行,因而会产生新的名称空间,用来存放类的变量名和函数名,可以通过__dict__查看。 __dict__查出字典,key为属性名,value为属性值
4、什么是绑定到对象的方法、如何定义,如何调用,给谁用?有什么特性
面向对象作业 1、类的属性和对象的属性有什么区别?
类属性是类和对象共有的 2、面向过程编程与面向对象编程的区别与应用场景? 3、类和对象在内存中是如何保存的。 4、什么是绑定到对象的方法,、如何定义,如何调用,给谁用?有什么特性 5、如下示例, 请用面向对象的形式优化以下代码 在没有学习类这个概念时,数据与功能是分离的,如下 def exc1(host,port,db,charset): conn=connect(host,port,db,charset) conn.execute(sql) return xxx def exc2(host,port,db,charset,proc_name) conn=connect(host,port,db,charset) conn.call_proc(sql) return xxx # 每次调用都需要重复传入一堆参数 exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;') exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字') 6、下面这段代码的输出结果将是什么?请解释。 class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print(Parent.x, Child1.x, Child2.x) Child1.x = 2 print(Parent.x, Child1.x, Child2.x) Parent.x = 3 print(Parent.x, Child1.x, Child2.x) 7、定义学校类,实例化出:北京校区、上海校区两个对象 校区独有的特征有: 校区名=“xxx” 校区地址={'city':"所在市",'district':'所在的区'} 多们课程名=['xxx','yyy','zzz'] 多个班级名=['xxx','yyy','zzz'] 校区可以: 1、创建班级 2、查看本校区开设的所有班级名 3、创建课程 4、查看本校区开设的所有课程名 8、定义出班级类,实例化出两个班级对象 班级对象独有的特征: 班级名=‘xxx’ 所属校区名=‘xxx’ 多门课程名=['xxx','yyy','zzz'] 多个讲师名=['xxx','xxx','xxx'] 班级可以: 1、查看本班所有的课程 2、查看本班的任课老师姓名 9、定义课程类,实例化出python、linux、go三门课程对象 课程对象独有的特征: 课程名=‘xxx’ 周期=‘3mons’ 价格=3000 课程对象可以: 1、查看课程的详细信息 10、定义学生类,实例化出张铁蛋、王三炮两名学生对象 学生对象独有的特征: 学号=10 名字=”xxx“ 班级名=['xxx','yyy'] 分数=33 学生可以: 1、选择班级 3、注册,将对象序列化到文件 11、定义讲师类,实例化出egon,lqz,alex,wxx四名老师对象 老师对象独有的特征: 名字=“xxx” 等级=“xxx”、 老师可以: 1、修改学生的成绩 12、用面向对象的形式编写一个老师类, 老师有特征:编号、姓名、性别、年龄、等级、工资,老师类中有功能 1、生成老师唯一编号的功能,可以用hashlib对当前时间加上老师的所有信息进行校验得到一个hash值来作为老师的编号 def create_id(self): pass 2、获取老师所有信息 def tell_info(self): pass 3、将老师对象序列化保存到文件里,文件名即老师的编号,提示功能如下 def save(self): with open('老师的编号','wb') as f: pickle.dump(self,f) 4、从文件夹中取出存储老师对象的文件,然后反序列化出老师对象,提示功能如下 def get_obj_by_id(self,id): return pickle.load(open(id,'rb')) 13、按照定义老师的方式,再定义一个学生类 14、抽象老师类与学生类得到父类,用继承的方式减少代码冗余 15、基于面向对象设计一个对战游戏并使用继承优化代码,参考博客 http://www.cnblogs.com/linhaifeng/articles/7340497.html#_label1
1、类的属性和对象的属性有什么区别
2
、面向过程编程与面向对象编程的区别与应用场景?
操作系统一般用面向过程,复杂的应用程序用面向对象
3、类和对象在内存中是如何保存的。
把对象共有的丢类里面放着,把对象独有的专门找空间放着,这样便于节省内存空间
4、什么是绑定到对象的方法,、如何定义,如何调用,给谁用?有什么特性
绑定方法和函数的区别,函数需要传值,绑定方法不需要传值,会将绑定者自动传值