面向对象编程初探
一、面向对象编程简介
''' 面向对象编程 核心是对象二字,对象的特征与技能的结合体 基于该思想编写的程序就好比在创造一个世界(世界是由一个个的对象组成的),程序员就是这个世界的上帝,对于上帝来说任何存在的事物都是对象,任何不存在的事物也可以创造出来,使一种上帝式的思维方式 优点: 可扩展性强 缺点:编程的复杂度高 类: 如果说对象是特征与技能的结合体,类则是一系列对象相似的特征与技能的结合 在现实世界中,一定先有一个具体的对象,然后随着人类文明的发展由人类站在不同角度总结出类 注意: 类是抽象的概念,而对象才是具体存在的事物 站在不同角度,可以总结出不同的类 在程序中,一定要先定义类,后调用类产生对象 '''
二、通过与面向过程编程的流程对比,引入类的定义
# 面向过程和面向对象流程上的不同之处 # 假设要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用一个dict表示: stinfo = { 'name': 'fred', 'score': 80 } # 处理成绩可以用函数实现,比如修改成绩 def score(stinfo): stinfo['score'] = 90 print(stinfo) # score(stinfo) # 如果采用面向对象的程序设计思想,首先思考的不是程序的执行流程,而是student这种数据类型应该被视为一个对象,这个对象拥有namne和score这两个属性,如果要修改学生成绩,首先必须创建出这个学生对应的对象,然后给对象发一个修改的消息 # 定义类: class Student(object): addr='shanghai' def __init__(self, name, score): self.name = name self.score = score def modified_score(self): self.score = 90 print(self) ''' 定义类时会立刻触发类体代码的运行,会产生一个类的名称空间,将类体代码运行过程中产生的名字都存到类的名称空间中 ps:定义类的本质就是创造出一个名称空间,用来存放名字的,即类就相当于一个容器 '''
''' __init__方法: 为对象初始化自己独有的特征 强调: 1、该方法内可以有任意的python代码 2、一定不能有返回值 '''
class Student(object): addr='shanghai' def __init__(self, name, score): self.name = name self.score = score def modified_score(self): self.score = 90 print(self) print(Student.__dict__) # 查看类的名称空间 ''' {'__module__': '__main__', 'addr': 'shanghai', '__init__': <function Student.__init__ at 0x03D4B660>, 'modified_score': <function Student.modified_score at 0x059A45D0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None} ''' # 查看 print(Student.addr) # 数据属性 print(Student.modified_score) # 函数属性 # 增加 Student.phone = 180000013 print(Student.phone) # 修改 Student.addr = 'beijing' print(Student.addr) # 删除 del Student.phone print(Student.phone)
''' 反射:是通过字符串来操作类或者对象的属性 此方法类和对象都可以使用 getattr() setattr() delattr() hasattr ''' class Student(object): addr='shanghai' def __init__(self, name, score): self.name = name self.score = score def modified_score(self): self.score = 90 print(self) #### getattr() 三个参数,(类/对象,字符串形式的属性名称,default) 查看属性的值 stu1 = Student('fred', 80) print(getattr(Student, 'addr')) # 等同于Student.__dict__['addr'] # print(getattr(Student,'phone')) print(getattr(Student, 'phone', None)) print(getattr(stu1, 'name')) ''' shanghai AttributeError: type object 'Student' has no attribute 'phone' # 查询一个不存在的属性,则报错 None # getattr还有第三个参数,可以加默认值,即属性存在,则返回属性的值,属性不存在,则返回默认值,不至于让程序报错 fred getattr同样适用于对象 ''' ### setattr() 三个参数,(类/对象,字符串形式的属性名,'属性的新值') 有则改值,无则新增 setattr(Student,'addr','ShangHai') # 等同于Student.addr='ShangHai' print(getattr(Student,'addr')) setattr(stu1,'name','Fred') print(getattr(stu1,'name')) setattr(stu1,'phone','187') print(getattr(stu1,'phone')) ''' ShangHai # 修改类属性的值,注意一旦修改了类的属性值,那么调用此类的所有对象都会被改 Fred # setattr()同样适用对象 187 # phone属性添加成功 ''' # delattr() 删除属性 两个参数(对象/类,'字符串形式的属性名字') delattr(stu1,'phone') # print(stu1.phone) ''' AttributeError: 'Student' object has no attribute 'phone' # 删除成功 ''' # havesttr() 判断属性是否存在,存在True 不存在False print(hasattr(stu1,'phone')) ''' False '''
三、使用类
''' 类的两种用途: 1.当做一个容器(名称空间) print(Student.__dict__) {'__module__': '__main__', 'addr': 'shanghai', '__init__': <function Student.__init__ at 0x04A45618>, 'modified_score': <function Student.modified_score at 0x04A455D0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None} 2、调用类产生或者实例化出对象 stu1 = Student('fred', 80) ''' class Student(object): addr='shanghai' def __init__(self, name, score): self.name = name self.score = score def modified_score(self): self.score = 90 print(self) # 调用类产生stu1对象(调用类的过程称之为实例化,得到的结果是一个类的实例/对象) ''' 调用类发生了两件事: 1、会产生一个空对象 2、会触发类中__init__函数的运行,将空对象连同括号内的参数一同传入 ''' stu1 = Student('fred', 80) # 调用Studen类产生s1的空对象,触发Studen.__init__('fred',80)绑定方法,stu1调用Stundent.__init方法,那么stu1就会当做第一个参数自动传入
四、属性查找及对象的绑定方法
class Student(object): addr = 'shanghai' def __init__(self, name, score): self.name = name self.score = score def modified_score(self): self.score = 90 print(self) def print_score(self): print('this is your score') ''' 属性查找: 对象的本质就是一个容器,即对象名称空间 类的本质也是一个容器,即类的名称空间 属性查找的顺序: 对象的名称空间———类的名称空间 如果类的名称空间没找到则报错 'Student' object has no attribute 'phone' ''' stu1 = Student('fred', 80) stu2 = Student('Fred_Li',90) print(id(stu1.addr)) print(id(stu2.addr)) print(stu1.addr) ''' 41736696 41736696 结论:类的数据属性是共享给所有对象 ''' ''' 类中定义的函数是类的函数属性,类可以使用,但类使用时就是一个普通的函数,必须遵守函数的规则 但是,类中定义的函数其实是给对象用的,而且是绑定给对象用,称为绑定方法 绑定方法的特殊之处: 绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入 ''' Student.print_score('xxx') # 类使用类中的函数,必须要给self传值Student.print_score() # 类使用类中的函数,必须要给self传值 ''' print_score() missing 1 required positional argument: 'self' ''' stu3=Student('Fred',90) # __init__(self, name, score) stu3当第一个参数自动传入 Fred和90分别传给name和score print(stu3.__init__) # <bound method Student.__init__ of <__main__.Student object at 0x04DB1B10>> __init__的绑定方法 print(stu1.__dict__) # 对象独有的特征
''' 类与类型,在Python3中统一了类与类型的概念,类就是类型 ''' class Student(object): addr='shanghai' def __init__(self, name, score): self.name = name self.score = score def modified_score(self): self.score = 90 print(self) print(type(Student),Student) print(type(list),list) ''' <class 'type'> <class '__main__.Student'> <class 'type'> <class 'list'> 即:list就是Python内置的类 而Student可以立即为自定义的类 ''' stu1=Student('fred',80) l1=list(['fred',20]) print(l1.append) print(stu1.modified_score) ''' <built-in method append of list object at 0x049F7698> <bound method Student.modified_score of <__main__.Student object at 0x049F1470>> 即: append是l1调用了list类的绑定方法 modified是stu1调用了Studentl类的绑定方法 第一个参数是对象自动传入的 '''
转载请注明出处:http://www.cnblogs.com/lichunke/