python 中的面向对象
2017-11-28 02:01
393 查看
面向对象
分类
面像过程编程:初学者容易接受,从上往下依次执行。面向函数编程:将某功能的代码封装为一个函数,使用时仅调用函数。
面向对象编程:对函数进行分类和封装
class people: # 经典类 class People(object): # 新式类,object类是所有类的基类/父类 def __init__(self,name,age): # 构造函数,当实例化对象时自动调用,self是实例化出来的对象 self.name = name # 属性(和字段好像叫法不同) self.age = age def run(self): # 方法 print "running...." def __del__(self): print "deleteing......" # 析构函数,删除实例化对象时自动调用; class Student(People): # Student是子类,继承People这个父类; pass p1 = People("张策",18) p1.run()
还有抽象类(除了经典类和新式类)
作用- 一个普通的接口(相当于API接口)
- 一种规范
也就是抽象类+抽象方法
from abc import ABCMeta,abstractmethod class Alert(object): __metaclass__ = ABCMeta @abstractmethod def send(self): pass class Foo(Alert): def __init__(self): print '__init__' def send(self): print '这里就是一种规范' f = Foo() f.send() #输出结果: __init__ 这里就是一种规范 #为什么说这里是一种规范,因为,在你前面定义的Alter类中send方法下面不能写任何方法,他只是一种规范,在Foo类中继承这个方法时,你需要和Alter类中有相同的方法,也就是send方法
析构函数 __del__
python虚拟机销毁对象是自动执行的方法,他不是销毁内存,销毁内存它是由Python自带的算法。都是在最后执行
__call__方法
class Foo: def __init__(self): pass def __del__(self): print "拜拜" def __call__(self): print "这里是__call__方法" f1 = Foo() f1() #这里相当于指向call方法 #输出结果: 这里是__call__方法 拜拜 #拜拜是在执行完释放内存
python中的静态和动态方法,静态和动态字段
#!/usr/bin/env python #coding:utf-8 class Province: memo = '你一定可以成为你想成为的人' #这里的memo变量属于整个类,而不是一个类中的某个方法,但是他可以通过对象和类调用。 def __init__(self,name,capital,leader): self.name = name #self 相当于动态字段 self.capital = capital self.leader = leader def suport_meet(self): #这个方法为动态方法 print self.name + "正在开运动会" #静态方法是由于面向对象编程才从java哪里引进,在编程时你必须要构造一个对象进行进行使用,如果进行构造,就会在内存中开辟空间,所以才使用了静态方法 @staticmethod #加了这个装饰器,相当于将动态方法,转化为静态方法,并且将self参数去掉 def Foo(): #如果有很多对象,我们可以不用实例化,直接进行类.方法,进行操作,节省实例化使用的内存空间 print '要努力学习,称为想成为的人' @property #加了这个装饰器,就相当于将方法变成特性,访问的方法和访问字段一样 def Bar(self): print '加油,努力' hb = Province('陕西','西安','飞天') print hb.leader print Province.memo print hb.memo hb.suport_meet() Province.Foo() hb.Bar #这里注意,self相当于hb,这里就先当于给hb.name等等赋值,hb就叫做对象 #在这里我们引出如果属于类的字段(也就是这里的demo),这类叫做静态字段,而self.name则是动态字段 #对象可以访问静态字段,建议在使用时,应禁止使用对象调用。 #类不能够访访问动态方法,他需要实例化,但是类可以访问静态方法 #输出结果: 飞天 你一定可以成为你想成为的人 你一定可以成为你想成为的人 陕西正在开运动会 要努力学习,称为想成为的人 加油,努力
私有方法和私有字段(外面可以访问和不可以访问)
私有字段
self.__name = name这是name这个字段就变成了,私有字段,这时你如果通过类.字段访问就会报错
AttributeError: Province instance has no attribute ‘__flag’(说我们没有这个属性)
这里我们只能通过内部的类进行间接访问
#!/usr/bin/env python #coding:utf-8 class Province: memo = '你一定可以成为你想成为的人' def __init__(self,name,capital,leader,flag): self.name = name self.capital = capital self.leader = leader self.__flag = flag def suport_meet(self): print self.name + "正在开运动会" @staticmethod def Foo(): print '要努力学习,称为想成为的人' @property def Bar(self): print '加油,努力' def show(self): print self.__flag hb = Province('陕西','西安','飞天',True) hb.show() #输出: True 还有一种方法:通过 @property,将内部的show方法修改 @property def show(self): return self.__flag #通过特性方法进行直接调用 print hb.show
私有方法(和私有字段相同的概念)
#!/usr/bin/env python #coding:utf-8 class Province: memo = '你一定可以成为你想成为的人' def __init__(self,name,capital,leader,flag): self.name = name self.capital = capital self.leader = leader self.__flag = flag def suport_meet(self): print self.name + "正在开运动会" @staticmethod def Foo(): print '要努力学习,称为想成为的人' @property def Bar(self): print '加油,努力' def show(self): print self.__flag def __sha(self): print '我真的很努力' hb = Province('陕西','西安','飞天',True) hb.__sha() #结果报错:Province instance has no attribute '__sha' 同样,在类的内部进行方访: def lala(self): self.__sha() hb = Province('陕西','西安','飞天',True) hb.lala() 同样第二种方法直接访问: hb._Province__sha()进行直接访问
只读特性和只写特性(新式类,经典类好像可以直接改)
新式类#!/usr/bin/env python #coding:utf-8 class Province(object): memo = '你一定可以成为你想成为的人' def __init__(self,name,capital,leader,flag): self.name = name self.capital = capital self.leader = leader self.__flag = flag def suport_meet(self): print self.name + "正在开运动会" @staticmethod def Foo(): print '要努力学习,成为想成为的人' @property def Bar(self): print '加油,努力' #这里就是只读 @property def show(self): return self.__flag #可以写的装饰器 @show.setter def show(self,value): self.__flag = value hb = Province('陕西','西安','飞天',True) print hb.show hb.show = False print hb.show #结果: True False
经典类
class test1(): def __init__(self): self.__pravite = 'feitian1' @property def show(self): return self.__pravite t1 = test1() print t1.show t1.show = 'change 1' print t1.show #输出结果: feitian1 change 1
什么是面向对象?
类 ===== 建房子的图纸 (三室一厅,两室一厅…….)对象===== 实际建出来的房子(门牌号)
class ThreeRoom:
pass
seven_zero_one = ThreeRoom()
seven_zero_one.live()
seven_zero_one.clean()
面向对象的三个特性:
封装
封装:把内容统一放在一个地方,看成一个整体,(实例化对象self和类的属性绑定在一起);访问封装内容的两种方式:
通过self去访问封装的内容;(self.name)
通过实例化的对象名去访问封装的内容;(p1 = People(“westos”,17) p1.age)
继承(子承父业)
新名词:基类/派生类, 父类/子类, 新式类和经典类多继承:
新式类: 广度优先继承;(python2.x和python3.x均支持)
经典类:深度优先继承;(python2.x支持,python3.x没有经典类)
注意: 类的方法中可以传递一个对象;
class People(object): # 新式类,object类是所有类的基类/父类 def __init__(self,name,age): # 构造函数,当实例化对象时自动调用; self.name = name # 属性 self.age = age print "%s is create...." %(self.name) def run(self): # 方法 print "%s running...." %(self.name) def __del__(self): print "deleteing......" # 析构函数,删除实例化对象时自动调用; class Relation(object): **def make_relation(self,obj):** #传入一个对象作为参数 print "%s is related with %s" %(self.name,obj.name) class Student(People,Relation): # Student是子类,继承People这个父类; def __init__(self,name, age, sid): # People.__init__(self,name,age) # 如果父类名更改,此处也需要更改; super(Student, self).__init__(name,age) # 更推荐使用 self.sid = sid class Teacher(People,Relation): def __init__(self, name, age, tid): #People.__init__(self,name,age) super(Teacher, self).__init__(name, age) self.tid = tid s1 = Student("lijian", 18, "007") t1 = Teacher("westos", 18, "001") s1.make_relation(t1)
继承中重写父类方法
class Father: def __init__(self): self.fname = 'fff' def Func(self): print 'father.funk' def Bad(self): print 'father.抽烟喝酒烫头' class Son(Father): def __init__(self): self.Sname = 'sss' def Bar(self): print 'Son.Bar' #这里相当于重写了父类的bad方法 def Bad(self): Father.Bad(self) print 'son.学习上网' s1 = Son() s1.Bar() s1.Func() #输出结果: Son.Bar father.funk father.抽烟喝酒烫头 son.学习上网
继承中调用父类构造方法
class Father(object): def __init__(self): self.fname = 'fff' print 'father.__init__' def Func(self): print 'father.funk' def Bad(self): print 'father.抽烟喝酒烫头' class Son(Father): def __init__(self): self.Sname = 'sss' print 'son.__init__' #Father.__init__(self) #经典类中的调用方法 super(Son, self).__init__() #新式类调用方法(建议使用这种方式) def Bar(self): print 'Son.Bar' def Bad(self): Father.Bad(self) print 'son.学习上网' s1 = Son() #输出结果 son.__init__ father.__init__
多类继承
-新式类(广度优先)class A(object): def __init__(self): print 'this is a' def save(self): print 'this is A.save' class B(A): def __init__(self): print 'this is B' class C(A): def __init__(self): print 'this is C' def save(self): print 'this is C.save' class D(B,C): def __init__(self): print 'this is D' c1 = D() c1.save() #输出结果: this is D this is C.save
经典类
class A: def __init__(self): print 'this is a' def save(self): print 'this is A.save' class B(A): def __init__(self): print 'this is B' class C(A): def __init__(self): print 'this is C' def save(self): print 'this is C.save' class D(B,C): def __init__(self): print 'this is D' c1 = D() c1.save() #输出结果: this is D this is A.save
多态
类的属性在内存中只需要存储一次
在构造函数中的属性,每实例化一个就要存储一次
class People(object): def __init__(self,name,country="China"): self.name = name self.country = country p1 = People("飞天") print p1.name p2 = People("lala") print p2.name #结果为: 飞天 lala
多态
如果子类调用的方法,子类没有,父类有,运行父类;
如果子类调用的方法,子类有,父类也有,只运行子类的;
面向对象进阶
类变量,全局变量在内存中只存储一份普通的对象属性,每个对象中都要存储一份
class People(object): # def __init__(self,name,age,country="china"): #每创建一个实例就会在内存中重新存储一次 # self.name=name # self.age=age # self.country=country country="China" #全局变量,类的属性,只需要存储一次 def __init__(self,name,age): self.name=name self.age=age def run(self): print "%s is running..."%self.name p1=People("mj",18) print p1.name ,p1.age,p1.country print id(People.country),id(p1.country)
特殊属性
装饰器property(前面已经介绍过,这里就不在说了)
他就是装饰函数的一个函数
#该方法实现了装饰器的功能,但是调用函数的方式发生了改变。 import time def dtimer(fun): def timer(*args,**kwargs): # 高阶函数 #args = (1,2,3,4) start_time = time.time() fun(*args,**kwargs) # args =(1,2,3,4), 解包*(1,2,3,4) stop_time = time.time() return "run %s" % (stop_time - start_time) return timer # 返回的是timer的地址,要执行该函数需要timer() @dtimer # fun1 = dtimer(fun1) def fun1(*args,**kwargs): print "in the fun1....." print args time.sleep(1) def fun2(): print "in the fun2....." time.sleep(0.5) print fun1(1,2,3,4) # print timer(fun2)
#类中的几种方法 class Date(object): def __init__(self,year, month,day): self.year = year self.month = month self.day = day def echo_date(self): print "Year:",self.year print "Month:",self.month print "Day:",self.day @classmethod def from_str(cls,s): # class,类方法的第一个参数是类本身,cls = Date year, month, day = map(int, s.split("-")) d = cls(year,month,day) # d = Date(year,month,day) return d # 对象 @staticmethod · def is_date_legal(s): # 静态方法,第一个参数既不是对象,也不是类本身, year, month, day = map(int, s.split("-")) return year >= 1970 and 0 < month <= 12 and 0 < day <= 31 #d = Date(2017,9,9) #d.echo_date() #d1 = Date.from_str('2018-10-19') #d1.echo_date() print "legal" if Date.is_date_legal('2017-13-16') else "illegal"
匿名函数
lambda 形参 : 返回值#这里的形参,可以赋默认值,形参和返回值都可以使用*args和**kwargs。 f = lambda x,y:x-y print f (1,2) #返回结果为1
断言
assert(1 == 1)作用:也就是判断条件
练习
#!/usr/bin/env python #coding:utf-8 """ class Person(object): def __init__(self,name,gene,weight): self.Name = name self.__Gene = gene if name != 'feitian': self.Gender = '男' self.Weight =weight self.Age = None def talk(self): print 'XXXX' def fight(self,weight): if self.Weight > weight: print '打' else: print '跑' p1 = Person('n1','a',190) p1.Age = 18 p2 = Person('n2','aa',50) p1.talk() p2.talk() p2.fight(p1.Weight) print p2.__dict__ #__dict__对象中的所有字段通过key_value的方法获取到并且输出(仅仅字段) print dir(p2) #dir(var也一样)获取类中的所有东西,包括__init__等 #输出结果: XXXX XXXX 跑 {'Gender': '\xe7\x94\xb7', 'Age': None, '_Person__Gene': 'aa', 'Name': 'n2', 'Weight': 50} ['Age', 'Gender', 'Name', 'Weight', '_Person__Gene', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'fight', 'talk'] """
相关文章推荐
- Python--day6--面向对象学习
- 面向对象之Python的链表实现(一)类的构造
- python面向对象思维导图
- python——面向对象基础
- Python面向对象基础一
- python面向对象实现K均值聚类
- 我的Python第五篇 面向对象
- python面向对象基础
- python(三):面向对象实现之打飞机游戏
- Python 面向对象基础知识
- Python 面向对象与 C++、Java 的异同
- 面向对象控与python内存泄漏
- python面向对象笔记(what)
- python学习总结(面向对象进阶)
- Python面向对象基础
- Python面向对象中的“私有化”
- python 进阶—面向对象和设计模式
- Python面向对象和图形用户界面(三)---- 其他GUI库 & 综合应用
- python面向对象代码示例
- Python学习笔记:面向对象基础