python 学习笔记day08-面向对象编程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 学习笔记day08-面向对象编程相关的知识,希望对你有一定的参考价值。
面向对象编程
OOP介绍
什么是OOP
编程的发展已经从简单控制流中按步的的指令序列进入到更有组织的方式中
结构化的或过程性编程可以让我们把程序组织成逻辑块,以便重复或重用
面向对象编程增强了结构化编程,实现了数据与动作的融合
数据层和逻辑层由一个可用以创建这些对象的简单抽象层来描述
常用术语
抽象/实现:抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于描绘程序结构,从而实现这种模型
封装/借口:封装描述了对数据/信息进行隐藏的观念,它对数据属性提供接口和访问函数;客户端根本就不需要知道在封装之后,数据属性是如何组织的,这就需要在设计时,对数据提供相应的接口
合成:合成扩充了对类的描述,使得多个不同的类合成为一个大的类,来解决现实问题
派生/继承:派生描述了子类的创建,新类保留已存类类型中所有需要的数据和行为,但允许修改或者其他的自定义操作,都不会修改原类的定义
多态:指出了对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体的类
类
创建类
类是一种数据结构,我们可以用它来定义对象,对象把数据值和行为特性融合在一起
python使用class关键字来创建类
通常类名的第一个字母大写
class ClassName(bases):
‘class documentation string‘ #类文档字符串
class_suite #类体
类里面定义的函数 叫方法
类的数据属性
数据属性仅仅是所定义的类的变量
这种属性已是静态变量,或者是静态数据。他们表示这些数据是与它们所属的类对象绑定的,不依赖于任何类实例
静态成员通常仅用来跟踪与类相关的值
>>> class C(object):
... foo = 100
...
>>> print C.foo
100
>>> C.foo += 1
>>> print C.foo
101
self指的是将对象本身传递到方法中,既将a对象本身传递到pstar方法中。
>>> class MyClass(object):
... def pstar(self):
... print ‘*‘ * 20
...
>>> a = MyClass()
>>> a.pstar()
********************
#!/usr/bin/env python
class AddrBook(object):
def __init__(self,nm,ph):
self.name = nm
self.phone = ph
self.city = "Beijing"
def get_name(self):
return self.name
def get_phone(self):
return self.phone
def update_phone(self,newph):
self.phone = newph
print "Now, %s phone number is: %s " % (self.name,self.phone)
if __name__ == ‘__main__‘:
bob = AddrBook("Bob Green","15011223344")
alice = AddrBook("Alice Smith","12255778899")
#print "%s: %s" % (bob.name,bob.phone) # 不应该直接使用类里面的数据属性,如果要是使用的话,需要定义一些类的方法
#print "%s: %s" % (alice.name,alice.phone)
print "%s: %s" % (bob.get_name(),bob.get_phone())
print "%s: %s" % (alice.get_name(),alice.get_phone())
bob.update_phone("186112233344")
print "%s: %s" % (bob.get_name(),bob.get_phone())
组合
什么是组合
类被定义后,目标就是要把它当成一个模块来使用,并把这些对象嵌入到你的代码中去
组合就是让不同的类混合并加入到其他类中来增加功能和代码重用性
可以在一个大点的类中创建其它类的实例,实现一些其他属性和方法来增强对原来的类对象
实现组合
创建复合对象、应用组合可以实现附加的功能
例如,通过组合实现上述地址簿功能的增强
#!/usr/bin/env python
class Info(object):
def __init__(self,ph,em,qq):
self.phone = ph
self.email = em
self.qq = qq
def get_phone(self):
return self.phone
def update_phone(self,newph):
self.phone = newph
class AddrBook(object):
def __init__(self,nm,ph,em,qq):
self.name = nm
self.info = Info(ph,em,qq)
if __name__ == ‘__main__‘:
bob = AddrBook("Bob Green","1250000000","[email protected]","11111111")
print bob.info.get_phone()
创建子类
当类之间有显著的不同,并且较小的类是较大的类所需要的组件时组合表现的很好;但当设计“相同的类但有些不同额功能”时,派生就是一个更加合理的选择了
OOP的更强大方面之一是能够使用一个已经定义好的类,扩展它或者对其进行修改,而不会影响系统中使用现存类的其他代码片段
OOD(面向对象设计)允许类特征在子孙类或子类中进行继承
继承
继承描述了基类的属性如何“遗传”给派生类
子类可以继承他的基类的任何属性,不管是数据属性还是方法
#!/usr/bin/env python
class AddrBook(object):
def __init__(self,nm,ph):
self.name = nm
self.phone = ph
self.city = "Beijing"
def get_name(self):
return self.name
def get_phone(self):
return self.phone
def update_phone(self,newph):
self.phone = newph
print "Now, %s phone number is: %s " % (self.name,self.phone)
class EmplAddrBook(AddrBook): #类 EmplAddrBook并没有定义任何方法
pass
if __name__ == ‘__main__‘:
bob = EmplAddrBook("Bob Green","111111122222333") #bob是类 EmplAddrBook的实例
print bob.get_phone() # 类 EmplAddrBook继承了类AddrBook的方法,实例bob就具备了该功能
通过继承覆盖方法
如果子类中有和父类同名的方法,父类方法将被覆盖
如果需要访问父类的方法,则需要调用一个未绑定的父类方法,明确给出子类的实例
>>> class P(object):
... def foo(self):
... print "in P-foo"
...
>>> class C(P):
... def foo(self):
... print "in C-foo"
...
>>> c = C()
>>> c.foo()
in C-foo
>>> P.foo(c)
in P-foo
#!/usr/bin/env python
class AddrBook(object):
def __init__(self,nm,ph):
self.name = nm
self.phone = ph
self.city = "Beijing"
def get_name(self):
return self.name
def get_phone(self):
return self.phone
def update_phone(self,newph):
self.phone = newph
print "Now, %s phone number is: %s " % (self.name,self.phone)
class EmplAddrBook(AddrBook):
def __init__(self,nm,ph,em,eid):
AddrBook.__init__(self,nm,ph)
self.email = em
self.eid = eid
def get_email(self):
return self.email
if __name__ == ‘__main__‘:
bob = EmplAddrBook("Bob Green","111111122222333","[email protected]","1024")
print bob.get_phone()
print bob.get_email()
多重继承
python允许多重继承,即一个类可以是多个父类的子类,子类可以拥有所有父类的属性
>>> class A(object):
... def foo(self):
... print "foo method"
...
>>> class B(object):
... def bar(self):
... print "bar methon"
...
>>> class C(A,B):
... pass
...
>>> c = C()
>>> c.foo()
foo method
>>> c.bar()
bar methon
特殊的类属性
属性 | 描述 |
C.__name__ | 类C的名字(字符串) |
C.__doc__ | 类C的文档字符串 |
C.__bases__ | 类C的所有父类构成的元组 |
C.__dict__ | 类C的属性 |
C.__module | 类C定义所在的模块 |
C.__class__ | 实例C对应的类 |
实例
创建实例
如果说类是一种数据结构定义类型,那么实例则声明了一个这种类型的变量
类被实例化得到实例,该实例的类型就是这个被实例化的类
创建实例与调用函数类似,调用一个类就创建了它的一个实例
>>> class C(object):
... foo = 100
...
>>> c = C()
>>> print c
<__main__.C object at 0x7f7f2d721350>
实例属性
实例仅拥有数据属性,数据属性只是与某个累的实例相关联的数据值,并且可通过句点属性标识法来访问
设置实例的属性可以在实例创建后任意时间进行,也可以在能够访问实例的代码中进行
>>> class C(object):
... pass
...
>>> c = C()
>>> c.hi = ‘hello‘
>>> print c.hi
hello
特殊的实例属性
类与实例属性对比
绑定方法
方法仅仅是类内部定义的函数,方法只有在其所属的类拥有实例时,才能被调用
任何一个方法定义中的第一个参数变量都是self,它表示调用此方法的实例对象
非绑定方法
调用非绑定方法并不常用到
需要调用一个没有实例的类中的方法的一个主要场景是你在派生一个子类,而且要覆盖父类的方法
class AddrBook(object):
def __init__(self,nm,ph):
self.name = nm
self.phone = ph
self.city = "Beijing"
class EmplAddrBook(AddrBook):
def __init__(self,nm,ph,em,eid):
AddrBook.__init__(self,nm,ph)
self.email = em
self.eid = eid
def get_email(self):
return self.email
类和实例的内建函数
函数 | 功能 |
rissubclass() | 判断一个类是另一个类的子类或子孙类 |
isinstance() | 在判定一个对象是否是另一个给定类的实例 |
hasattr() | 判断一个对象是否有一个特定的属性 |
getattr() | 获得一个对象的属性值 |
setattr() | 设置一个对象的属性 |
delattr() | 删除一个对象的属性 |
私有化
python为类元素(属性和方法)的私有性提供初步的形式,由双下划线开始的属性在运行时被“混淆”,所以直接访问是不允许的
>>> class C(object):
... def __init__(self,nm):
... self.__name = nm
... def getName(self):
... return self.__name
...
>>> c = C(‘bob‘)
>>> c.getName()
‘bob‘
>>> c.__name #私有化的数据不能在外部直接使用
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: ‘C‘ object has no attribute ‘__name‘
>>> c._C__name
‘bob‘
#!/usr/bin/env python
#coding: utf8
class Book(object):
def __init__(self,title,author):
self.title = title
self.author = author
def __str__(self):
return self.title
def __call__(self):
print "%s is written by %s" % (self.title,self.author)
if __name__ == ‘__main__‘:
pybook = Book("Core Pyhon","Wesley")
print pybook # 因为类中定义了__str__方法,此处打印出的内容是__str__的返回值
pybook() #调用pybook就是执行 __call__方法中的代码
左加法,右加法,左减法,右减法
#!/usr/bin/env python
#coding: utf8
class MyNumber(object):
def __init__(self,num):
self.number = num
def __add__(self,other):
return self.number + other
def __radd__(self,other):
return self.number + other
def __sub__(self, other):
return self.number - other
def __rsub__(self, other):
return other - self.number
if __name__ == ‘__main__‘:
digit = MyNumber(10)
print digit + 10 # 用__add__实现
print 10 + digit # __radd__
print digit - 100 # __sub__
print 100 - digit # __rsub__
魔法方法不是随便起名字的。必须遵循对应的名字
本文出自 “linux服务器” 博客,请务必保留此出处http://sailq21.blog.51cto.com/6111337/1866140
以上是关于python 学习笔记day08-面向对象编程的主要内容,如果未能解决你的问题,请参考以下文章