面向对象
8.1 类的定义和使用
# 类体代码在类的定义阶段就会立刻执行 class Student: school='oldboy' #数据属性 def learn(self): #函数属性 print('is learning') def choose_course(self): #函数属性 print('choose course') print(Student) print(Student.__dict__) #查看类属性 #查看 print(Student.school) #数据属性 print(Student.learn) #函数属性 #增加 Student.country='China' print(Student.country) #修改 Student.school='Oldboy' print(Student.school) #删除 del Student.country print(Student.country) print(Student.learn) Student.learn('xxxxx')
8.2 对象的定义和使用
class Student: school='oldboy' #stu1,'李三炮','男',18 def __init__(self,name,sex,age): #在调用类时会自动触发执行 self.Name=name self.Sex=sex self.Age = age def learn(self): print('is learning') def choose_course(self): print('choose course') #调用类的过程又称之为实例化:stu1=Student('李三炮','男',18) #1、得到一个返回值,即对象,该对象是一个空对象stu1 #2、Student.__init__(stu1,'李三炮','男',18) stu1=Student('李三炮','男',18) print(stu1.__dict__) print(stu1.Name,stu1.Age,stu1.Sex) stu2=Student('张铁蛋','女',38) stu3=Student('武大郎','男',28) print(stu2.__dict__) print(stu3.__dict__) print(stu1,stu2,stu3) print(stu2.Name)
8.3 属性查找与绑定方法
x=1 class Student: school='oldboy' # Name='xxx' def __init__(self,name,sex,age): #在调用类时会自动触发执行 self.Name = name self.Sex = sex self.Age = age def learn(self,x,y): print('%s is learning' %self.Name) print(x,y) def choose_course(self): print('choose course') def commit_hw(): print('commit homework') #1、查找一个对象的属性顺序是:先找对象自己的__dict__,再找类的__dict__ stu1=Student('李三炮','男',18) print(stu1.__dict__) print(stu1.Name) print(stu1.school) print(stu1.x) stu1=Student('李三炮','男',18) stu2=Student('张铁蛋','女',38) stu3=Student('武大郎','男',28) # 2、类的数据属性是所有对象共享,所有对象都指向同一个内存地址 stu1.school='xxx' Student.school='Oldgirl' print(Student.school,id(Student.school)) print(stu1.school,id(stu1.school)) print(stu2.school,id(stu2.school)) print(stu3.school,id(stu3.school)) # 3、类中定义的函数是绑定给对象使用: # 3.1:不同对象就是不同绑定方法 # 3.2:绑定给谁,就应该由谁来调用,谁来调用就会把谁当做第一个参数传给对应的函数 print(Student.learn) print(stu1.learn) print(stu2.learn) print(stu3.learn) stu1.learn(1,2) #Student.learn(stu1,1,2) stu2.learn(1,3) stu3.learn(1,4) print(Student.learn) stu1.commit_hw()
class Garen: #定义英雄盖伦的类,不同的玩家可以用它实例出自己英雄; camp='demacia' #所有玩家的英雄(盖伦)的阵营都是Demacia def __init__(self,nickname,life_value,aggresivity): self.nickname=nickname #为自己的盖伦起个别名 self.life_value=life_value #英雄都有自己的生命值 self.aggresivity=aggresivity #英雄都有自己的攻击力 def attack(self,enemy): #普通攻击技能,enemy是敌人 enemy.life_value-=self.aggresivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值 class Riven: camp = 'Noxus'所有玩家的英雄(锐雯)的阵营都是Noxus; def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity def fire(self,enemy): enemy.life_value-=100 g1=Garen('草丛猥琐男',1000,100) r1=Riven('猛男雯雯',200,500) print(r1.life_value) g1.attack(r1) print(r1.life_value)
8.4 继承与派生
http://www.cnblogs.com/snailgirl/p/8513785.html
8.5 组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...
class People: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class Course: def __init__(self,name,period,price): self.name=name self.period=period self.price=price def tell_info(self): print('<%s %s %s>' %(self.name,self.period,self.price)) class Teacher(People): def __init__(self,name,age,sex,job_title): People.__init__(self,name,age,sex) self.job_title=job_title self.course=[] self.students=[] class Student(People): def __init__(self,name,age,sex): People.__init__(self,name,age,sex) self.course=[] egon=Teacher('egon',18,'male','沙河霸道金牌讲师') s1=Student('牛榴弹',18,'female') python=Course('python','3mons',3000.0) linux=Course('python','3mons',3000.0) #为老师egon和学生s1添加课程,组合 egon.course.append(python) egon.course.append(linux) s1.course.append(python) #为老师egon添加学生s1,组合 egon.students.append(s1) #使用 for obj in egon.course: obj.tell_info()
8.6 抽象类
import abc class File(metaclass=abc.ABCMeta): @abc.abstractmethod def read(self): pass @abc.abstractmethod def write(self): pass class Disk(File): def read(self): print('disk read') def write(self): print('disk write') class Process(File): def read(self): print('Process read') def write(self): print('Process write') d=Disk() p=Process() d.read() d.write() p.read() p.write()
8.7 多态和多态性
8.7.1 多态
多态指的是一类事物有多种形态
动物有多种形态:人,狗,猪
import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @abc.abstractmethod def talk(self): pass class People(Animal): #动物的形态之一:人 def talk(self): print('say hello') class Dog(Animal): #动物的形态之二:狗 def talk(self): print('say wangwang') class Pig(Animal): #动物的形态之三:猪 def talk(self): print('say aoao')
8.7.2 多态性
多态性是指在不考虑实例类型的情况下使用实例
多态性分为静态多态性和动态多态性
静态多态性:如任何类型都可以用运算符+进行运算
动态多态性:如下
peo=People() dog=Dog() pig=Pig() #peo、dog、pig都是动物,只要是动物肯定有talk方法 #于是我们可以不用考虑它们三者的具体是什么类型,而直接使用 peo.talk() dog.talk() pig.talk() #更进一步,我们可以定义一个统一的接口来使用 def func(obj): obj.talk()
>>> class Cat(Animal): #属于动物的另外一种形态:猫 ... def talk(self): ... print('say miao') ... >>> def func(animal): #对于使用者来说,自己的代码根本无需改动 ... animal.talk() ... >>> cat1=Cat() #实例出一只猫 >>> func(cat1) #甚至连调用方式也无需改变,就能调用猫的talk功能 say miao ''' 这样我们新增了一个形态Cat,由Cat类产生的实例cat1,使用者可以在完全不需要修改自己代码的情况下。使用和人、狗、猪一样的方式调用cat1的talk方法,即func(cat1) '''
鸭子类型
例1:利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法
#二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用 class TxtFile: def read(self): pass def write(self): pass class DiskFile: def read(self): pass def write(self): pass
例2:其实大家一直在享受着多态性带来的好处,比如Python的序列类型有多种形态:字
符串,列表,元组,多态性体现如下
#str,list,tuple都是序列类型 s=str('hello') l=list([1,2,3]) t=tuple((4,5,6)) #我们可以在不考虑三者类型的前提下使用s,l,t s.__len__() l.__len__() t.__len__() len(s) len(l) len(t)
8.8 封装
http://www.cnblogs.com/snailgirl/p/8513810.html
8.9 绑定方法与非绑定方法
#绑定方法:绑定给谁就应该由谁来调用,谁来调用就会把谁当做第一个参数自动传入 #非绑定方法:在类内部用staticmethod装饰的函数即非绑定方法,就是普通函数 import settings import hashlib import time class MySQL: def __init__(self,host,port): self.host=host self.port=port def func(self): print('%s 说:你好啊我的天' %self.name) @classmethod def from_conf(cls):#classmehtod是给类用的,即绑定到类,类在使用时会将类本身当做参数传给类方法的第一个参数(即便是对象来调用也会将类当作第一个参数传入) return cls(settings.HOST,settings.PORT) @staticmethod def create_id(n): #statimethod不与类或对象绑定,谁都可以调用,没有自动传值效果 m=hashlib.md5() m.update(str(time.clock()+n).encode('utf-8')) return m.hexdigest() # conn=MySQL('127.0.0.1',3306) conn=MySQL.from_conf() # print(conn.host,conn.port) print(MySQL.create_id(1)) print(conn.create_id(2))
import settings class MySQL: def __init__(self,host,port): self.host=host self.port=port @staticmethod def from_conf(): return MySQL(settings.HOST,settings.PORT) # @classmethod #哪个类来调用,就将哪个类当做第一个参数传入 # def from_conf(cls): # return cls(settings.HOST,settings.PORT) def __str__(self): return '就不告诉你' class Mariadb(MySQL): def __str__(self): return '<%s:%s>' %(self.host,self.port) m=Mariadb.from_conf() print(m) #我们的意图是想触发Mariadb.__str__,但是结果触发了MySQL.__str__的执行,打印就不告诉你: