当前位置: 首页 > 后端技术 > Python

Python自学日记13-类与方法

时间:2023-03-26 14:25:46 Python

1.运算符重载通过定义其他特殊方法,您可以为用户定义类型的各种运算符指定行为。例如,如果为Time类定义一个add方法,则可以在Time对象类Time(object)上使用+运算符:def__init__(self,hour=0,minute=0,second=0):self.小时=小时self.minute=分钟self.second=秒deftime_to_int(time):minutes=time.hour*60+time.minuteseconds=minutes*60+time.secondreturnsecondsdefincrement(self,seconds):seconds+=self.time_to_int()returnint_to_time(seconds)defprint_time(time):print('%.2d:%.2d:%.2d'%(time.hour,time.minute,time.second))defis_after(self,other):returnself.time_to_int()>other.time_to_int()def__str__(self):返回'%.2d:%.2d:%.2d'%(self.hour,self.minute,self.second)def__add__(self,other):seconds=self.time_to_int()+other.time_to_int()returnint_to_time(seconds)当你对一个时间对象应用+运算符时,python调用add,当你打印结果时,python调用str#修改运算符的行为,使其可以作用于用户自定义类型,这个过程称为运算符重载start=Time(9,45)duration=Time(1,35)print(start+duration)原来两个时间对象是不能相加的,但是通过定义add方法,可以实现两个时间对象的相加。2.基于类型的分配为Point对象写一个add方法,它可以接受一个对象或一个元组。如果第二个操作对象是一个Point方法,该方法应该返回一个新的Point对象,其x坐标是两个操作对象的x坐标之和,与y坐标相似。如果Diego操作数是元组,则该方法将第一个元素添加到x坐标,将第二个元素添加到y坐标,并返回包含相加结果的Point对象。首先需要判断传入的第二个参数的类型和第一个参数的类型是否一致。这里需要使用内置函数isinstance来接收一个值和一个类对象(当然也可以换成列表、元组等),如果类型相同则返回True,否则返回假。然后为每个case设置一个method,达到上面的效果。类Point(object):def__init__(self,x,y):self.x=xself.y=ydefprint_point(p):print('(%g,%g)'%(p.x,p.y))def__str__(self):返回'(%g,%g)'%(self.x,self.y)defincrement(self,other):返回(self.x+other[0]),(self.y+other[1])def__add__(self,other):ifisinstance(other,Point):returnself.add_point(other)else:returnincrement(self,other)#这里写错了,应该写成returnself.increment(other)defadd_point(self,other):返回(self.x+other.x),(self.y+other.y)blank=Point(1,2)white=Point(2,3)print(blank+white)返回(3,5)结果是对的,返回试下元组print(blank+(2,3))-------------------------------------------------------------------------NameErrorTraceback(最近调用最后)in---->1print(blank+(2,3))in__add__(self,other)14returnself.add_point(other)15else:--->16returnincrement(self,other)17defadd_point(self,other):18return(self.x+other.x),(self.y+other.y)NameError:name'increment'isnotdefined错误显示增量没有定义。我去上课,发现第二种情况的代码是错误的。您应该使用方法而不是函数。修改代码后classPoint(object):def__init__(self,x,y):self.x=xself.y=ydefprint_point(p):print('(%g,%g)'%(p.x,p.y))def__str__(self):return'(%g,%g)'%(self.x,self.y)defincrement(self,other):return(self.x+other[0]),(self.y+other[1])def__add__(self,other):ifisinstance(other,Point):returnself.add_point(other)else:returnself.increment(other)defadd_point(self,other):return(self.x+other.x),(self.y+other.y)然后报同样的错误。按照说明,已经修改成功,应该返回正确的值,但是还是报错。这意味着修改类时需要重启服务器。判断的标准是我把这段代码复制到另一个页面是正常的返回值。这个页面,已经报错了,所以重启jupyternotebook后,就可以正常显示了。记得在哪里看到修改类需要重启服务器。3.编写一个名为Kangaroo的类,它有以下方法。将属性pouch_contents(口袋里的东西)初始化为空列表的__init__方法。一种put_in_pouch方法,它接受任何类型的对象并将其添加到pouch_contents。一个__str__方法,它返回袋鼠对象和口袋内容的字符串表示形式。创建两个Kangaroo对象,将它们分配给kanga和roo,并将roo添加到kanga的口袋中。袋鼠类(对象):def__init__(self,pouch_contents=[]):self.pouch_contents=pouch_contentsdefput_in_pouch(self,a):self.pouch_contents.append(a)def__str__(self):返回'%s'%self.pouch_contentskanga=Kangaroo([1])roo=Kangaroo([2])kanga.put_in_pouch(roo)print(kanga)这是我看到这个问题时想到并写的代码,但是有个小问题在它,pouch_contents=[]在初始化期间不可扩展。如果修改类,原来的写法会相应改变,所以对答案代码中的第一个方法进行了调整:classKangaroo(object):def__init__(self,contents=None):ifcontents==None:contents=[]self.pouch_contents=contentsdefput_in_pouch(self,a):self.pouch_contents.append(a)def__str__(self):return'%s'%self.pouch_contents有内容的默认值。如果不传参数,则按照默认值进行处理。如果能根据传入参数处理传入参数,扩展性会更好。然后答案代码也处理了第三种方法,但是和我的不同classKangaroo(object):def__init__(self,contents=None):ifcontents==None:contents=[]self.pouch_contents=contentsdefput_in_pouch(self,a):self.pouch_contents.append(a)def__str__(self):"""返回这个袋鼠和袋子内容的字符串表示,每行一个项目"""t=[object.__str__(self)+'withpouchcontents:']forobjinself.pouch_contents:s=''+object.__str__(obj)t.append(s)return'\n'.join(t)我基本上可以理解了这个方法,我对object.__str__(self)有些疑惑,暂时还是无法理解。上网查了一下,发现涉及到一些继承问题。等学习了继承再回来看这个问题。