您的位置:首页 > 编程语言 > Python开发

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']
"""
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: