Python语言程序设计课件 第8章 类与面向对象_第1页
Python语言程序设计课件 第8章 类与面向对象_第2页
Python语言程序设计课件 第8章 类与面向对象_第3页
Python语言程序设计课件 第8章 类与面向对象_第4页
Python语言程序设计课件 第8章 类与面向对象_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章类与面向对象CATALOGUE目录01对象和类02面向对象03datetime库04综合实例:简易记事本01对象和类基本概念对象以面向对象方式构造的软件,其运行过程就是通过软件对象之间的消息发送来完成各种任务。程序对象通常是在软件执行过程中动态产生的。为了让程序运行时能够按需动态产生软件对象,程序员在编写程序的时候需要预先定义好对象的“模板”,也就是为相同类型的对象定义属性(也称为成员变量)和行为(也称为方法),这种“模板”被称为类。类软件系统中的对象最初来源于现实生活中的对象的概念,包含属性和行为,可能是对现实事物的抽象,也可能是虚构的事物。基本概念类示例图8-1代表类Paper和类Pencil的模板>>>isinstance(3,int)True>>>n=3>>>isinstance(n,int)True通过BIF函数isinstance()判断一个对象是否是一个类的实例__init__()方法常被用来进行对象的初始化操作。这里,我们利用魔法方法__init__()来为对象属性赋初值。初值可以来自于__init__()的入口参数,也可以直接在__init__()方法中赋予一个默认的初始值。类的定义1.初始化2.特殊参数selfPython语言中的魔法方法是一组Python语言预先设定的方法,其名称以双下划线开头和结尾,通常读作dunderxxx(对于__xxx__()方法),意为doubleunderscore。魔法方法通常用来增强自定义类的功能。3.魔法方法1

classPaper():2

def__init__(self):3

self.content=None4

defrecord(self):5

pass6

deffold(self):7

pass8

classPencil():9

def__init__(self,state):10

self.state=state11

defwrite(self):12

pass13

defdraw(self):14

pass15

defspin(self):16

passPython语法要求类的方法的第一个参数必须是该方法调用所对应的对象本身实例化类>>>myPaper=Paper()>>>myPencil=Pencil('全新')>>>print(myPaper)<__main__.Paperobjectat0x00000213624F9F60>>>>print(myPencil)<__main__.Pencilobjectat0x00000213624FA680>实例化类1.对方法和属性的访问1

classPaper():2

def__init__(self):3

self.content=None4

defrecord(self,content):5

self.content=content6

deffold(self):7

print("我变成飞机啦!")8

defread(self):9

print(self.content)10

classPencil():11

def__init__(self,state):12

self.state=state13

defwrite(self,paper):14

paper.record("我是一条记录")15

self.state="一半"16

defdraw(self,paper):17

paper.record("我是一幅铅笔画")18

self.state="笔头"19

defspin(self):20

print("转我,转我,转我!")21

defget_state(self):22

print(self.state)>>>myPaper.fold()我变成飞机啦!>>>myPencil.spin()转我,转我,转我!Python语言中通过点标记法访问对象的属性和方法。实例化类2.对象之间的交互对象之间的协作才是面向对象程序的利器。>>>myPencil.write(myPaper)>>>myPaper.read()我是一条记录>>>myPencil.draw(myPaper)>>>myPaper.read()实例化类3.删除对象del语句可以用来删除一个对象。但是需要注意,有时删除的实际上是变量对对象的引用,而不是对象本身。>>>delmyPaper>>>myPaper.read()Traceback(mostrecentcalllast):……NameError:name'myPaper'isnotdefined.Didyoumean:'Paper'?实例化类4.对象的唯一标识有时我们需要判断两个变量是否引用同一个对象,可以通过is或者isnot对象身份比较运算符来实现。>>>yourPaper=myPaper>>>yourPaperismyPaperTrue>>>yourPaperisnotmyPaperFalse02面向对象封装通常指的是将数据和操作数据的方法组织在一起,使外部对数据的访问通过调用相应的方法来实现,而不是直接操作数据。封装有利于隐藏实现细节,向外部的访问提供一个独立于内部实现的抽象接口。当内部数据或者方法实现发生变化时,只要接口不变,外部的访问就不会受到影响。封装-基本概念封装-可见性控制名称以单下划线开头的属性和方法通常被视为是受保护的,只有类和其子类(子类的概念参见后面的继承)内部的代码可以访问。名称以双下划线开头(但不以双下划线结尾)的属性和方法通常被视为是私有的,只有类自身能够访问。其它不以下划线开头的属性和方法则被视为是公开的,可以在类外部直接访问。1

classPaper():2

def__init__(self):3

self.__content="我是一张白纸"4

defread(self):5

print(self.__content)>>>paper=Paper()>>>paper.read()我是一张白纸>>>print(paper.__content)Traceback(mostrecentcalllast):……AttributeError:'Paper'objecthasnoattribute'__content'.封装-特殊变量__all__特殊变量__all__是一个字符串列表,可以用来声明包或者模块对外部访问开放的公共接口,是实现包或者模块封装的一种机制,代表了模块或者包的设计者希望呈现给访问者的信息。如下定义意味着package包的设计者希望向外开放对内部模块module_a和子包subpackage_b的访问,屏蔽对其它内部模块和包的访问。1

#package/__init__.py2

__all__=[‘module_a’,‘subpackage_b’]继承是一个从已有类派生新类的机制,它使得我们可以重用已有类的属性和方法,只在新类中按需定义新的属性和方法,避免“重复造轮子”。被继承的类通常被称为父类、基类或者超类,新的类通常被称为子类或者派生类。继承-基本概念1

classMechanicalPencil(Pencil):2

defrefill(self):3

self.state=‘新’>>>mech_pencil=MechanicalPencil('新')>>>paper=Paper()>>>mech_pencil.draw(paper)>>>mech_pencil.get_state()'笔头'>>>mech_pencil.refill()>>>mech_pencil.get_state()'新'子类对继承方法的重写会覆盖原方法的定义(仅在子类范围内,对于父类没有影响),可以通过BIF函数super()调用父类的方法。继承-重写与super()方法>>>mech_pencil=MechanicalPencil('新',0.4)>>>mech_pencil.get_state()新1

classMechanicalPencil(Pencil):2

def__init__(self,size):3super().__init__(state)4self.size=size5defrefill(self):6self.state='新'7defget_size(self):8print(self.size)多态通常指的是相同的操作可以作用于不同类型的对象,表现出不同的行为。Python对于多态的支持包括子类多态、鸭子类型、运算符重载等。多态-基本概念Python语言支持被称为“鸭子类型”的多态形式,即“如果它走路像鸭子、游泳象鸭子,那么它就是鸭子”。这里强调的是对象的行为,而不是对象的类型。也就是说,只要对象能够执行我们期望的操作(即具有我们需要的方法或属性),我们就可以把它当作是某种类型,而无需关心它所属类的继承关系。多态-鸭子类型1

classPerson():2

defread(self):3

print("猜猜我在想什么")4

defread_content(obj):5

obj.read()>>>my_paper=Paper()

>>>me=Person()

>>>read_content(my_paper)

>>>read_content(me)我是一张白纸猜猜我在想什么运算符重载使得相同的运算符可以作用于不同类型的对象从而实现不同的运算。Python语言中,运算符重载可以借助魔法方法实现。多态-运算符重载1

def__eq__(self,other):2

ifnotisinstance(other,Pencil):3

raiseTypeError('另一个对象不是铅笔!')4

ifself.state==other.state:5

returnTrue6

else:7

returnFalse>>>my_pencil=Pencil('新')

>>>your_pencil=Pencil('新')>>>paper=Paper()>>>my_pencil==your_pencilTrue>>>my_pencil.draw(paper)>>>my_pencil==your_pencilFalse03datetime库datetime是以面向对象方式处理日期和时间的标准库。基本概念【知识拓展】UTC协调世界时UTC时是目前世界上主要采用的时间标准,基于原子钟计时。UTC时的精准度优于大家熟知的格林威治标准时间(GMT),因为后者基于天文观测计时,会受到地球自转周期不规则的影响。UTC标准时间对应时区UTC00:00,而北京时间对应时区为UTC08:00。【知识拓展】计算机系统时钟计算机系统通常提供一个系统时钟,这个系统时钟通过硬件电路记录从某个时间点(这个时间点被称为纪元‘epoch’)开始到当前所经过的时间,其它软件基于这个系统时间来计算各种日期时间。大部分计算机系统中的纪元为UTC+00:00时区时间1970年1月1日0时0分0秒(换算成北京时间就是1970年1月1日8时0分0秒)。利用这个系统时钟,再结合本机操作系统中设置的本地时区,就可以正确换算出计算机本地时间了。实例化类datetime的常用方法分两类:一类是直接从本机系统获取当前日期时间来构造datetime对象;一类是需要提供明确的日期时间值来构造datetime对象。类datetime的使用-实例化功能:返回本地当前日期和时间构成的datetime对象参数:tz作为可选参数,指定时区,默认为None(表示采用计算机系统本地设定的时区)。(1)datetime.now(tz=None)功能:返回当前UTC标准日期和时间构成的datetime对象参数:无(2)datetime.utcnow()>>>fromdatetimeimportdatetime>>>dt=datetime.now()>>>utc_dt=datetime.utcnow()>>>print('本地日期和时间:',dt)Localdateandtime:2023-08-2921:47:23.184413>>>print('UTC日期和时间:',utc_dt)UTCdateandtime:2023-08-2913:47:35.160911类datetime的使用-实例化功能:通过类datetime实例化对象参数:必须提供年、月、日作为初始化参数,时、分、秒、毫秒、时区等参数可选。(3)datetime(year,month,day,hour=0,minute=0,second=0,microsecond=0,tzinfo=None,*,fold=0)功能:从ISO格式(ISO8601)的日期时间字符串产生一个datetime对象参数:date_sting为ISO格式日期时间字符串(4)datetime.fromisoformat(date_string)>>>fromdatetimeimportdatetime>>>dt=datetime(2023,8,29,9,0,0,0)>>>print(dt)2023-08-299:00:00>>>fromdatetimeimportdatetime>>>dt1=datetime.fromisoformat('2023-08-29')>>>print(dt1)2023-08-2900:00:00>>>dt2=datetime.fromisoformat('2023-08-2909:00:00.000')>>>print(dt2)2023-08-2909:00:00类datetime的使用-实例化功能:按照自定义格式字符串format解析输入的时间date_string,产生一个datetime对象。(5)

datetime.strptime(date_string,format)>>>fromdatetimeimportdatetime

>>>dt1=datetime.strptime("2023/08/29","%Y/%m/%d")

>>>print(dt1)2023-08-2900:00:00>>>dt2=datetime.strptime("2023/08/2912:00:00","%Y/%m/%d%H:%M:%S")

>>>print(dt2)2023-08-2912:00:00类datetime的主要属性datetime类的重要实例属性如下,它们都是只读的,除了tzinfo以外都是整数类型。我们可以通过datetime类的实例直接读取它们:yearmonthdayhourminutesecondmicrosecondtzinfo:时区信息类datetime的主要方法类datetime提供了大量实例方法用于实现不同形式的日期时间的输出:方法功能备注replace()更改datetime对象的日期时间以及时区信息中的某些属性,其它属性不变。

astimezone()更改datetime对象的时区,该对象的日期时间属性值也相应发生变化。

timestamp()返回datetime对象对应的浮点数值形式日期时间值。与前文介绍的实例化方法fromtimestamp()等相对应。isoformat()返回datetime对象对应的ISO8601格式表示的日期时间字符串。与前文介绍的实例化方法fromisoformat()相对应。strftime()按照自定义的格式输出日期时间字符串。常用的格式控制符号参见第四章。04综合实例:简易记事本简易记事本的主要功能是用于记录各种事件,以备查阅。用户对记事本的使用一般来说可以包括以下几方面:记录事件:用户输入事件名、起始和终止时间,要求系统记录该事件;查找事件:用户输入日期,查找记录中是否存在匹配的事件;查看所有事件:用户要求列出记事本中所有事件的详细信息;删除事件:用户输入事件名,删除某个事件;排序事件:用户要求按照持续时长排序并查看事件。需求分析从需求中,容易识别出,这里至少涉及了两类对象:记事本和事件。尝试把需求分别分派给这两类对象。其中事件相关的信息和对事件的操作分派给事件类classMyEvent,与用户交互的功能由记事本类classMyNotepad承担。系统设计系统实现-

classMyEvent的实现1

classMyEvent:2

def__init__(self,name,start_time,end_time):3

#尝试解析时间字符串4

try:5

self.start_time=datetime.strptime(start_time,"%Y-%m-%d%H:%M:%S")6

self.end_time=datetime.strptime(end_time,"%Y-%m-%d%H:%M:%S")7

exceptValueError:8

raiseValueError("Invaliddate/timeformat.Use'YYYY-MM-DDHH:MM:SS'.")9

#检查开始时间是否早于或等于结束时间10

ifself.start_time>self.end_time:11

raiseValueError("Starttimemustbebeforeorequaltoendtime.")12

=name13

def__str__(self):14

"""魔法方法便于打印输出"""15

returnf"Event:{},StartTime:{self.start_time.strftime('%Y-%m-%d%H:%M:%S')},EndTime:{self.end_time.strftime('%Y-%m-%d%H:%M:%S')}"16

defduration(self):17

"""计算事件的持续时间"""18

returnself.end_time-self.start_time19

defis_within_date(self,date):20

"""检查事件是否在给定的日期内"""21

returnself.start_time.date()<=date<=self.end_time.date()系统实现-

classMyNotePad的实现1

classMyNotepad:2

def__init__(self):3

self.events=[]4

defadd_event(self,event):5

self.events.append(event)6

defremove_event(self,event_name):7

self.events=[eventforeventinself.eventsif!=event_name]8

deflist_events(self):9

foreventinself.events:10

print(event)11

deffind_events_by_date(self,date_str):12

"""搜索给定日期涉及的事件"""13

date=datetime.strptime(date_str,"%Y-%m-%d").date()14

events_on_date=[eventforeventinself.events15

ifevent.is_within_date(date)]16

returnevents_on_date17

defsort_events_by_duration(self):18

"""把事件按照持续时间从短到长排序"""19

self.events.sort(key=lambdax:x.duration())测试1

#创建一些事件2

event1=MyEvent("复习功课","2024-08-0109:30:00","2024-08-0111:30:00")3

event2=MyEvent("朋友小聚","2024-08-0112:30:00","2024-08-0113:30:00")4

event3=MyEvent("面试","2024-08-0209:00:00","2024-08-0210:00:00")5

#创建记事本并添加事件6

notepad=MyNotepad()7

notepad.add_event(event1)8

notepad.add_event(event2)9

notepad.add_event(event3)10

#列出所有事件11

print("\n所有事件:")12

notepad.list_events

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论