python学习之面向对象学习
2017-06-12 19:11
309 查看
一、什么事面向对象,以及面向对象的优点? 面向过程优缺点: 我们知道面向过程是流水线式的编程,过程就是解决问题的步骤,把大的问题化解成小的模块 面向过程优点: 极大的降低了程序的复杂度 面向过程缺点: 牵一发而动全身, 所以完成一个模块很少改动,否则改动的地方比较多 面向对象优缺点: 面向对象编程的核心是对象,由属性和函数构成 面向对象优点: 解决程序的扩展性,对某个类的修改能反映到整个体系中 类的语法结构: class 类名: 类体 例子: class People: language = 'Chinese' def func(self): #self把对象自身传进去 pass p1 = People p2 = People print(p1.language) print(p2.language) p1.language = 'english' print(p1.language) #输出english print(p2.language) #输出english 注: 所有对象共用类的属性,所以p2也输出english 初始化类__init__ 例子: class Garen: camp='Demacia' def __init__(self,nickname, aggressivity=58,life_value=456): self.nickname = nickname self.aggressivity = aggressivity self.life_value = life_value def attack(self,enemy): enemy.life_value -= self.aggressivity hero = Garen('garen', 100, 600) #加括号初始化类对象 print(isinstance(hero, Garen)) #isinstance判断hero是否是类Garen的实例,是则返回True,否则返回False print(Garen.__name__) #类的名称 print(Garen.__doc__) #类的文档字符串 print(Garen.__base__) #类的第一个父类 print(Garen.__bases__) #类的所有父类构成的元组 print(Garen.__dict__) #类的字典属性 print(Garen.__module__) #类定义所在的模块 print(Garen.__class__) #实例对应的类 将函数绑定到对象上叫做对象的方法,并且会把自身传递给函数作为第一个参数 对象的交互: class Riven: camp = 'Noxus' def __init__(self, nickname, aggressivity=54,life_value=300): self.nickname = nickname self.aggressivity = aggressivity self.life_value = life_value def attack(self,enemy): enemy.life_value -= self.aggressivity r1 = Riven('瑞问问') print(hero.life_value) r1.attack(hero) print(hero.life_value) print(id(r1.attack)) #id打印函数位置 print(id(Riven.attack)) 类有两种属性:数据属性和函数属性,数据属性共享给所有对象。 方法是绑定到所有对象上的,并且对象会传递给函数 创建对象就是创建了一个命名空间,对象会先找自己的命名空间,再找类的命名空间 二、继承 继承是一种创建新类的方式 继承的好处,减少代码冗余, 子类覆盖父类的方法叫做派生 例子: class ParentClass1: pass class ParentClass2: pass class SubClass1(ParentClass1): pass class SubClass2(ParentClass1,ParentClass2): pass print(SubClass1.__bases__) #打印父类 print(SubClass2.__bases__) #打印父类 继承关系如图:
F->A->E-B->D->C
F->D->B-E->C->H->A
派生类 例子: class Animal: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def eat(self): print('eating') def talk(self): print('%s 正在叫' %self.name) class People(Animal): def __init__(self,name,age,sex,education): Animal.__init__(self,name,age,sex) self.education = education def talk(self): Animal.talk(self) print('%s say hello' %self.name) class Pig(Animal): pass class Dog(Animal): pass peo1 = People('hyh',20,'male','小学毕业') pig1 = Pig('zhangsan', 16, 'male') dog1 = Dog('lisi', 16, 'female') peo1.talk() pig1.talk() dog1.talk() print(isinstance(peo1, People)) #判断peo1是否是People类,返回True或False print(isinstance(pig1, Pig)) #继承反映的什么是什么的关系 print(isinstance(dog1, Dog)) 通过__dict__获取属性 class Sub: def __init__(self): self.bar = 123 def bar(self): print('Sub.bar') s = Sub() print(s.__dict__) print(s.__dict__['bar']) 组合: 在一个类中,以另外一个类的对象作为数据属性,称为类的组合,组合反映的是什么有什么的关系, 例子: class People: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class Date: def __init__(self,year,mon,day): self.year = year self.mon = mon self.day = day def tell(self): print('%s-%s-%s' %(self.year,self.mon,self.day)) class Teacher(People): def __init__(self,name,age,sex,salary,year,mon,day): self.name = name self.age = age self.sex = sex self.salary = salary self.birth = Date(year,mon,day) class Student(People): def __init__(self,name,age,sex,year,mon,day): self.name=name self.age=age self.sex=sex self.birth=Date(year,mon,day) t=Teacher('egon',18,'male',3000,1995,12,31) t.birth.tell() 定义类模拟接口 例子: class File: def read(self): raise TypeError('类型错误') def write(self): raise TypeError('类型错误') class Txt(File): def read(self): print('文本数据的读取方法') def write(self): print('文本数据的读取方法') class Sata(File): def read(self): print('硬盘数据的读取方法') def wirte(self): print('硬盘数据的读取方法') class Process(File): def read(self): print('进程数据的读取方法') def write(self): print('进程数据的读取方法') p = Process() p.read() t = Txt() d = Sata() print(isinstance(p, Process)) print(isinstance(t, Txt)) print(isinstance(d, Sata)) 注: File类定义功能函数,Txt,Sata,Process分别定义实现函数的方法 调用父类用super方法 例子: class Foo1: def test(self): print("from foo1.test") class Foo2: def test(self): print('from foo2.test') class Bar(Foo1,Foo2): def test(self): super().test() print('Bar') b = Bar() b.test()
三、封装
封装:主要为了保护数据的隐私,而把数据隐藏起来,只能通过接口去访问 类中通过__双下划线来隐藏数据属性和函数属性,含有__x的属性都会变成_类名__x的形式:
Foo: __x = __test(): () (Foo.)
封装实例: class People: __country = 'China' def __init__(self,name,age,sex): self.__name = name #self._People__name = name self.__age = age self.__sex = sex def tell_info(self): print('人的名字是:%s, 人的年龄是: %s, 人的性别是: %s' %(self.__name, self.__age, self.__sex)) p = People('alex', 29, 'male') print(p.__dict__) p.tell_info() 注: 封装只在定义时检查语法 p.__x = 1 print(p.__x) #打印1 修改属性接口 class People: def __init__(self,name,age): self.__name = name self.__age = age def tell_info(self): print('人的名字是: %s, 人的年龄是: %s' %(self.__name, self.__age)) def set_info(self,x, y): if not isinstance(x, str): raise TypeError('名字必须是字符串') if not isinstance(y, int): raise TypeError('年龄必须是整数') self.__name = x self.__age = y p = People('alex', 20) p.tell_info() p.set_info('hyh', 18) p.tell_info() 四、特性 property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值 例子: class People: def __init__(self,name,weight,height): self.name=name self.weight=weight self.height=height @property def bmi(self): return self.weight / (self.height**2) p1=People('egon',75,1.85) print(p1.bmi) 将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是 执行了一个函数然后计算出来的,这种特性的使用方式遵循统一访问原则 五、绑定方法与非绑定方法 类中定义的函数分成两大类: 一:绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入): 1. 绑定到类的方法:用classmethod装饰器装饰的方法。 为类量身定制 类.boud_method(),自动将类当作第一个参数传入 (其实对象也可调用,但仍将类当作第一个参数传入) 2. 绑定到对象的方法:没有被任何装饰器装饰的方法。 为对象量身定制 对象.boud_method(),自动将对象当作第一个参数传入 (属于类的函数,类可以调用,但是必须按照函数的规则来,没有自动传值那么一说) 二:非绑定方法:用staticmethod装饰器装饰的方法 1. 不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说。就是一个普通工具而已 注意:与绑定到对象方法区分开,在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,可不是普通函数, 对象调用该方法会自动传值,而staticmethod装饰的方法,不管谁来调用,都没有自动传值一说。 例子: import hashlib import time class MySQL: def __init__(self,host,port): self.id=self.create_id() self.host=host self.port=port @staticmethod def create_id(): #就是一个普通工具 m=hashlib.md5(str(time.clock()).encode('utf-8')) return m.hexdigest() print(MySQL.create_id) #<function MySQL.create_id at 0x0000000001E6B9D8> #查看结果为普通函数 conn=MySQL('127.0.0.1',3306) print(conn.create_id) #<function MySQL.create_id at 0x00000000026FB9D8> #查看结果为普通函数 classmehtod是给类用的,即绑定到类,类在使用时会将类本身当做参数传给类方法的第一个 参数(即便是对象来调用也会将类当作第一个参数传入),python为我们内置了函数classmethod来把类中的函数定义成类方法 例子: settings.py文件内容 HOST='127.0.0.1' PORT=3306 import settings import hashlib import time 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) print(MySQL.from_conf) #<bound method MySQL.from_conf of <class '__main__.MySQL'>> conn=MySQL.from_conf()print(conn.host,conn.port) conn.from_conf() #对象也可以调用,但是默认传的第一个参数仍然是类
相关文章推荐
- Dive into python 第5和6章面向对象学习笔记
- python学习之--面向对象
- Python学习(18)面向对象
- python学习第十五天 -面向对象之继承和多态
- [Python学习笔记][第六章Python面向对象程序设计]
- Python菜鸟学习手册09----面向对象续
- Python学习笔记(2)--面向对象
- python学习之路-8 面向对象之进阶
- Python面向对象高级编程——学习笔记
- python学习(七):面向对象(二)
- python学习笔记(七) - 面向对象高级编程
- Python面向对象学习资料汇总
- python学习笔记六之面向对象相关下(基础篇)
- python2.7学习笔记(10) ——面向对象高级编程
- 【python学习】多线程 与 面向对象 结合的一个经典例子
- python学习小结9:面向对象
- python学习----------面向对象2
- Python面向对象学习(2)
- python学习笔记六之初识面向对象上(基础篇)
- 廖雪峰python学习笔记9:面向对象高级