




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第十三章 面向对象编程 引言 面向对象编程 类 实例 绑定与方法调用 子类,派生和继承 内建函数 定制类 私有性 授权与包装 新式类的高级特性 相关模块class MyNewObjectType(bases):define MyNewObjectType classclass_suite #类体类是对象的定义,而实例是真正的实物,它存放了类中所定义的对象的具体信息创建一个实例的过程称作实例化,(留意:没有使用new 关键字):myFirstObject = MyNewObjectType()最简单的情况,类仅用作名称空间namespaces)class MyData(object):pass
2、mathObj = MyData() mathObj.x = 4 mathObj.y = 5 mathObj.x + mathObj.y9 mathObj.x * mathObj.y20方法class MyDataWithMethod(object): # 定义类def printFoo(self): # 定义方法print You invoked printFoo()!self代表实例对象本身创建一个类类定义)class AddrBookEntry(object): # 类定义address book entry classdef _init_(self, nm, ph): # 定义构造器s
3、 = nm # 设置 nameself.phone = ph # 设置 phoneprint Created instance for:, def updatePhone(self, newph): # 定义方法self.phone = newphprint Updated phone# for:, 创建实例实例化) john = AddrBookEntry(John Doe, 408-555-1212) #为John Doe 创建实例 jane = AddrBookEntry(Jane Doe, 650-555-1212) #为Jane D
4、oe 创建实例 john John Doe john.phone408-555-1212方法调用 john.updatePhone(415-555-1212) #更新John Doe 的电话 john.phone415-555-1212创建子类靠继承来进行子类化是创建和定制新类类型的一种方式,新的类将保持已存在类所有的特性,而不会改动原来类的定义指对新类的改动不会影响到原来的类)class EmplAddrBookEntry(AddrBookEntry):def _init_(self, nm, ph, id, em):AddrBookEntry._init_(self, n
5、m, ph)self.empid = idself. = emdef updateEmail(self, newem):self. = newemprint Updated address for:, john = EmplAddrBookEntry(John Doe, 408-555-1212,42, johnspam.doe)Created instance for: John Doe #给John Doe 创建实例 john john.phone408-555-1212 john.johnspam.doe john.updatePhone(415-555-1212)
6、Updated phone# for: John Doe john.phone415-555-1212 john.updateEmail(johndoe.spam) Updated address for: John Doe john.johndoe.spam面向对象编程编程的发展已经从简单控制流中按步的指令序列进入到更有组织的方式中,依靠代码块可以形成命名子程序和完成既定的功能。结构化的或过程性编程可以让我们把程序组织成逻辑块,以便重复或重用。增强了结构化编程,实现了数据与动作的融合:数据层和逻辑层现在由一个可用以创建这些对象的简单抽象层来描述。笼统/实现抽象指对现实世界问题和实体的本质表现
7、,行为和特征建模,建立一个相关的子集,可以用于描绘程序结构,从而实现这种模型。抽象不仅包括这种模型的数据属性,还定义了这些数据的接口。对某种抽象的实现就是对此数据及与之相关接口的现实化.封装/接口封装描述了对数据/信息进行隐藏的观念,它对数据属性提供接口和访问函数。在设计时,对数据提供相应的接口,以免客户程序通过不规范的操作来存取封装的数据属性。合成合成扩充了对类的描述,使得多个不同的类合成为一个大的类派生/承继/继承结构派生描述了子类的创建,新类保留已存类类型中所有需要的数据和行为,但允许修改或者其它的自定义操作,都不会修改原类的定义。继承描述了子类属性从祖先类继承这样一种方式。继承结构表示
8、多“代派生,可以描述成一个“族谱”,连续的子类,与祖先类都有关系。泛化/特化泛化表示所有子类与其父类及祖先类有一样的特点.特化描述所有子类的自定义,也就是,什么属性让它与其祖先类不同。多态对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体的类。多态表明了动态又名,运行时绑定的存在,允计重载及运行时类型确定和验证。类类把数据值和行为特性融合在一起,是现实世界的抽象的实体以编程形式出现。实例是这些对象的具体化。类声明与函数声明很相似,头一行用一个相应的关键字,接下来是一个作为它的定义的代码体class ClassName(object):class documentation str
9、ing #类文档字符串class_suite #类体类的数据属性 class C(object):. foo = 100 print C.foo100 C.foo = C.foo + 1 print C.foo101方法class MyClass(object):def myNoActionMethod(self):pass mc = MyClass() MyClass.myNoActionMethod() Traceback (innermost last):File , line 1, in ?MyClass.myNoActionMethod()TypeError: unbound met
10、hod must be called with class instance 1st argument mc.myNoActionMethod()类属性C._name_ 类的名字字符串)C._doc_ 类的文档字符串C._bases_ 类的所有父类构成的元组C._dict_ 类的属性C._module_ 类定义所在的模块C._class_ 实例对应的类初始化:通过调用类对象来创建实例 class MyClass(object): # define class 定义类. pass mc = MyClass() # instantiate class 初始化类_init_() 构造器方法把创建实例
11、的调用当成是对构造器的调用。解释器创建一个实例后调用的第一个方法._del_() 解构器方法解构器是在实例释放前提供特殊处理功能的方法.class C(P): # class declaration 类声明def _init_(self): # constructor 构造器print initializeddef _del_(self): # destructor 解构器P._del_(self) # call parent destructor print deleted c1 = C() # instantiation initialized 实例初始化initialized c2 =
12、c1 # create additional alias 创建另外一个别名 id(c1), id(c2) (11938912, 11938912) del c1 # remove one reference 清除一个引用 del c2 # remove another reference 清除另一个引用deletedclass InstCt(object):count = 0 # count is class attrdef _init_(self): # increment countInstCt.count += 1def _del_(self): # decrement countIns
13、tCt.count -= 1def howMany(self): # return count 返回countreturn InstCt.count a = InstTrack() b = InstTrack() b.howMany()2 a.howMany()2 del b a.howMany()1 del a InstTrack.count0实例属性能够在“运行时创建实例属性设置实例的属性可以在实例创建后任意时间进行,也可以在能够访问实例的代码中进行。class HotelRoomCalc(object):def _init_(self, rt, sales=0.085, rm=0.1):
14、self.salesTax = salesself.roomTax = rmself.roomRate = rtdef calcTotal(self, days=1):daily = round(self.roomRate *14 (1 + self.roomTax + self.salesTax), 2)return float(days) * daily实例属性 vs 类属性类属性仅是与类相关的数据值,类属性和实例无关,和实例属性不同。静态成员不会因为实例而改变它们的值访问类属性 class C(object):. version = 1.2 # static member c = C()
15、 # instantiation C.version # access via class1.2 c.version # access via instance1.2 C.version += 0.1 # update via class C.version # class access 类访问1.3 c.version # instance access, 1.3 # also reflected change class Foo(object):. x = 1.5 foo = Foo() foo.x1.5 foo.x = 1.7 # try to update class attr foo
16、.x # looks good so far. 1.7 Foo.x # nope, just created a new inst attr 1.5类属性持久性 class C(object):. spam = 100 # class attribute 类属性 c1 = C() # create an instance 创建一个实例 c1.spam # access class attr thru inst. 100 C.spam += 100 # update class attribute C.spam # see change in attribute200 c1.spam # con
17、firm change in attribute200类属性可变 class Foo(object):. x = 2019: poe2 foo = Foo() foo.x2019: poe2 foo.x2019 = valid path foo.x2019: poe2, 2019: valid path Foo.x2019: poe2, 2019: valid path绑定和方法调用调用绑定方法,实例可以调用mc.foo()调用非绑定方法class EmplAddrBookEntry(AddrBookEntry):def _init_(self, nm, ph, em):AddrBookEnt
18、ry._init_(self, nm, ph)self.empid = idself. = em组合一个类被定义后,目标就是要把它当成一个模块来使用,并把这些对象嵌入到你的代码中去,同其它数据类型及逻辑执行流混合使用。组合(composition)。就是让不同的类混合并加入到其它类中,来增加功能和代码重用性。class NewAddrBookEntry(object): # class definitiondef _init_(self, nm, ph): # define constructor 定义构造器 = Name(nm) # create Name instance
19、self.phone = Phone(ph) # create Phone instanceprint Created instance for:, 子类和派生创建子类class SubClassName (ParentClass1, ParentClass2, .):class_suite如果你的类没有从任何祖先类派生,可以使用object 作为父类的名字。经典类的声明唯一不同之处在于其没有从祖先类派生此时,没有圆括号:class ClassicClassWithoutSuperclasses:passclass Parent(object): # define paren
20、t classdef parentMethod(self):print calling parent methodclass Child(Parent): # define child classdef childMethod(self):print calling child method p = Parent() # instance of parent 父类的实例 c = Child() # instance of child 子类的实例 c.childMethod() # child calls its methodcalling child method c.parentMethod
21、() # calls parents methodcalling parent method承继class P: # parent class 父类 def _init_(self): print instance of,self._class_._name_class C(P): # child class 子类 pass c = C() # child instance 子类实例instance of C c._class_ # class that created us C._bases_ # childs parent class(es)(,)继承覆盖Overriding方法class
22、 P(object):def foo(self):print Hi, I am P-foo() p = P() p.foo()Hi, I am P-foo()class C(P):def foo(self):print Hi, I am C-foo() c = C() c.foo()Hi, I am C-foo()class C(P): def foo(self): P.foo(self) # super(C, self).foo()print Hi, I am C-foo() c = C() c.foo()Hi, I am P-foo() Hi, I am C-foo()class Sort
23、edKeyDict(dict): def keys(self): return sorted(super(SortedKeyDict,self).keys()d = SortedKeyDict(zheng-cai, 67), (hui-jun, 68),(xin-yi, 2)print By iterator:. key for key in dprint By keys():. d.keys()By iterator: zheng-cai, xin-yi, hui-junBy keys(): hui-jun, xin-yi, zheng-cai多重继承class P1: #(object):
24、 # parent class 1 父类1def foo(self): print called P1-foo()class P2: #(object): # parent class 2 父类2def foo(self): print called P2-foo()def bar(self): print called P2-bar()class C1(P1, P2): # child 1 der. from P1, P2passclass C2(P1, P2): # child 2 der. from P1, P2def bar(self): print called C2-bar()cl
25、ass GC(C1, C2): # define grandchild class经典类 gc = GC() gc.foo() # GC = C1 = P1called P1-foo() gc.bar() # GC = C1 = P1 = P2called P2-bar()新式类 gc = GC() gc.foo() # GC = C1 = C2 = P1called P1-foo() gc.bar() # GC = C1 = C2called C2-bar()类、实例和其他对象的内建函数issubclass(sub, sup)布尔函数判断一个类是另一个类的子类或子孙类。isinstance(
26、obj1, obj2),判断obj1 是类obj2 的一个实例,或者是obj2 的子类的一个实例hasattr(), getattr(),setattr(), delattr() class myClass(object):. def _init_(self):. self.foo = 100 myInst = myClass() hasattr(myInst, foo)True getattr(myInst, foo)100 hasattr(myInst, bar) Falsedir()dir()作用在实例上经典类或新式类时,显示实例变量,还有在实例所在的类及所有它的基类中定义的方法和类属性
27、。dir()作用在类上经典类或新式类时,则显示类以及它的所有基类的_dict_中的内容。dir()作用在模块上时,则显示模块的_dict_的内容。dir()不带参数时,则显示调用者的局部变量。vars(obj=None) 返回obj 的属性及其值的一个字典;如果没有给出obj,vars()显示局部名字空间字典属性及其值)class C(object):pass c = C() c.foo = 100 c.bar = Python vars(c)foo: 100, bar: Python用特殊方法定制类C._init_(self, arg1, .) 构造器带一些可选的参数)C._new_(sel
28、f, arg1, .)a 构造器带一些可选的参数);通常用在设置不变数据类型的子类。C._del_(self) 解构器C._str_(self) 可打印的字符输出;内建str()及print 语句C._repr_(self) 运行时的字符串输出;内建repr() 和 操作符C._unicode_(self)b Unicode 字符串输出;内建unicode()C._call_(self, *args) 表示可调用的实例C._nonzero_(self) 为object 定义False 值;内建bool() (从2.2 版开始)C._len_(self) “长度”(可用于类);内建len()C.
29、_getattr_(self, attr) 获取属性;内建getattr();仅当属性没有找到时调用C._setattr_(self, attr, val) 设置属性C._delattr_(self, attr) 删除属性C._getattribute_(self, attr) a 获取属性;内建getattr();总是被调用C._get_(self, attr) a (描述符获取属性C._set_(self, attr, val) a (描述符设置属性C._delete_(self, attr) a (描述符删除属性C._*add_(self, obj) 加;+操作符C._*sub_(sel
30、f, obj) 减;-操作符C._*mul_(self, obj) 乘;*操作符C._*div_(self, obj) 除;/操作符C._*truediv_(self, obj) 除;/操作符C._*floordiv_(self, obj) Floor 除;C._*mod_(self, obj) 取模/取余;%操作符C._*divmod_(self, obj) 除和取模;内建divmod()C._*pow_(self, obj, mod) 乘幂;内建pow();*操作符C._*lshift_(self, obj) 左移位;操作符C._*and_(self, obj) 按位与;&操作符C
31、._*or_(self, obj) 按位或;|操作符C._*xor_(self, obj) 按位与或;操作符C._neg_(self) 一元负C._pos_(self) 一元正C._abs_(self) 绝对值;内建abs()C._invert_(self) 按位求反;操作符C._complex_(self, com) 转为complex(复数C._int_(self) 转为int;内建int()C._long_(self) 转为long;内建long()C._float_(self) 转为float;内建float()数值类型:基本表示法String)C._oct_(self) 八进制表示;
32、内建oct()C._hex_(self) 十六进制表示;内建hex()C._coerce_(self, num) 压缩成同样的数值类型;内建coerce()C._index_(self)g 在有必要时,压缩可选的数值类型为整型比如:用于切片索引等等)简单定制class RoundFloatManual(object): def _init_(self, val): assert isinstance(val, float),“must be a float! self.value = round(val, 2) rfm = RoundFloatManual(4.2) print rfmdef
33、_str_(self):return str(self.value) print rfm4.2class Time60(object): # ordered pairdef _init_(self, hr, min):self.hr = hr # assign hoursself.min = min # assign minutesdef _str_(self):return %d:%d % (self.hr, self.min)def _add_(self, other):return self._class_(self.hr + other.hr, self.min + other.min
34、) mon = Time60(10, 30) tue = Time60(11, 15) print mon+tue21:45def _iadd_(self, other):self.hr += other.hrself.min += other.minreturn self mon =Time60(10,30) tue =Time60(11,15) id(mon)401872 mon += tue id(mon)401872 mon21:45v迭代器RandSeq 和AnyIter) from randseq import RandSeq for eachItem in RandSeq(. (
35、rock, paper, scissors):. print eachItemScissorsscissorsrockpaperpaperscissorsclass AnyIter(object):class AnyIter(object): def _init_(self, data, safe=False): def _init_(self, data, safe=False): self.safe = safe self.safe = safe self.iter = iter(data) self.iter = iter(data) def _iter_(self): def _ite
36、r_(self): return self return self def next(self, howmany=1): def next(self, howmany=1): retval = retval = for eachItem in range(howmany): for eachItem in range(howmany): try: try:retval.append(self.iter.next()retval.append(self.iter.next() except StopIteration: except StopIteration:if self.safe:if s
37、elf.safe:breakbreakelse:else:raiseraise return retval return retval a = AnyIter(range(10) i = iter(a) for j in range(1,5): print j, :, i.next(j)1 : 02 : 1, 23 : 3, 4, 54 : 6, 7, 8, 9*多类型定制NumStr)类NumStr,数字-字符对n:s加: NumStr1+NumStr2 表示n1+n2:s1+s2乘: NumStr1*NumStr2=n1*n:s1*n比较:(n1n2) 且 (s1s2)时,前往 1,(n1
38、n2)且(s1s2)时,前往-1,数值和字符串都一样时,或是两个比较的结果正相反时(即(n1s2),或相反),返回0class NumStr(object): def _init_(self, num=0, string=): self._num = num self._string = string def _str_(self): # define for str() return %d : %r % self._num, self._string) _repr_ = _str_ def _nonzero_(self): # False if both are return self._n
39、um or len(self._string) def _norm_cval(self, cmpres):# normalize cmp() return cmp(cmpres, 0) def _cmp_(self, other): # define for cmp() return self._norm_cval(cmp(self._num, other._num) + self._norm_cval(cmp(self._string, other._string)class NumStr(object):def _add_(self, other): # define for s+o if
40、 isinstance(other, NumStr): return self._class_(self._num +other._num,self._string + other._string) else: raise TypeError, Illegal for built-in operationdef _mul_(self, num): # define for o*n if isinstance(num, int): return self._class_(self._num * num, self._string * num) else: raise TypeError, Ill
41、egal for built-in operation私有化1.只提供访问函数来访问其值,实现隐藏2.由双下划线开始的属性在运行时被“混淆”,直接访问是不允许的3.self._num 属性为例,用于访问这个数据值的标识就变成了self._NumStr_num。4.可以防止在祖先类或子孙类中的同名冲突。在类中有一个_XXX 属性,它将不会被其子类中的_XXX 属性覆盖授权 包装:对一个已存在的对象进行包装,不管它是数据类型,还是一段代码,可以是对一个已存在的对象,增加新的,删除不要的,或者修改其它已存在的功能。实现授权授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给
42、对象的默认属性。class WrapMe(object): def _init_(self, obj): self._data = obj def get(self): return self._data def _repr_(self): return self._data def _str_(self): return str(self._data) def _getattr_(self, attr): return getattr(self._data, attr) wrappedComplex = WrapMe(3.5+4.2j) wrappedComplex 3.5+4.2j wra
43、ppedComplex.real3.5 wrappedComplex.imag4.2 wrappedComplex.conjugate()(3.5-4.2j) wrappedComplex.get()(3.5+4.2j) wrappedList = WrapMe(123, foo, 45.67) wrappedList.append(bar) wrappedList123, foo, 45.67, bar wrappedList.index(45.67)2 f = WrapMe(open(/etc/motd) f.get() f.readline()Have a lot of fun.012
44、f.tell()21class WrapMe(object): def _init_(self, obj): self._data = obj def get(self): return self._data def _repr_(self): return self._data def _str_(self): return str(self._data) def _getattr_(self, attr): return getattr(self._data, attr)from time import time, ctimeclass TimedWrapMe(object): def _
45、init_(self, obj): self._data = obj self._ctime = self._mtime = self._atime = time() def gettimeval(self, t_type): if not isinstance(t_type, str) or t_type0 not in cma: raise TypeError,argument ofc,m,or areqd return getattr(self, _%s_%stime % (self._class_._name_, t_type0) def gettimestr(self, t_type
46、): return ctime(self.gettimeval(t_type) def _getattr_(self, attr): # delegate self._atime = time() return getattr(self._data, attr) def _repr_(self): # repr() self._atime = time() return self._data timeWrappedObj = TimedWrapMe(932) timeWrappedObj.gettimestr(c)Wed Apr 26 20:47:41 2019 timeWrappedObj.
47、gettimestr(a)Wed Apr 26 20:47:41 2019 timeWrappedObj932 timeWrappedObj.gettimestr(c)Wed Apr 26 20:47:41 2019 timeWrappedObj.gettimestr(a)Wed Apr 26 20:48:05 2019class CapOpen(object): def _init_(self, fn, mode = r, buf = -1): self.file = open(fn, mode, buf) def _repr_(self): return str(self.file) def _iter_(self): return iter(self.file)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 航空器飞行中的空中交通管制协调机制考核试卷
- 缫丝生产过程中的质量控制考核试卷
- 2025年中国地毯垫市场调查研究报告
- 基础会计考试试题及答案
- 美术骨干考试试题及答案
- 金工理论考试试题及答案
- 美容证考试试题及答案
- 机电初学考试试题及答案
- 公务员历史考试题及答案
- 应知应会考试 答案天津
- GA 255-2022警服长袖制式衬衣
- GB/T 5202-2008辐射防护仪器α、β和α/β(β能量大于60keV)污染测量仪与监测仪
- GB/T 39560.4-2021电子电气产品中某些物质的测定第4部分:CV-AAS、CV-AFS、ICP-OES和ICP-MS测定聚合物、金属和电子件中的汞
- GB/T 3452.4-2020液压气动用O形橡胶密封圈第4部分:抗挤压环(挡环)
- 计划生育协会基础知识课件
- 【教材解读】语篇研读-Sailing the oceans
- 抗肿瘤药物过敏反应和过敏性休克
- 排水管道非开挖预防性修复可行性研究报告
- 交通工程基础习习题及参考答案
- 线路送出工程质量创优项目策划书
- 100T汽车吊性能表
评论
0/150
提交评论