python中编写类的各种技巧和方法_python自学日记13——类和方法

1.操作符重载

通过定义其他的特殊方法,你可以为用户定义类型的各种操作符制定行为。例如,如果你为Time类定义一个add方法,则可在时间对象上使用+操作符

class Time(object):

def __init__(self,hour=0,minute=0,second=0):

self.hour=hour

self.minute=minute

self.second=second

def time_to_int(time):

minutes=time.hour*60+time.minute

seconds=minutes*60+time.second

return seconds

def increment(self,seconds):

seconds+=self.time_to_int()

return int_to_time(seconds)

def print_time(time):

print('%.2d:%.2d:%.2d'%(time.hour,time.minute,time.second))

def is_after(self,other):

return self.time_to_int()>other.time_to_int()

def __str__(self):

return '%.2d:%.2d:%.2d'%(self.hour,self.minute,self.second)

def __add__(self,other):

seconds=self.time_to_int()+other.time_to_int()

return int_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坐标也类似。

如果迭戈操作对象是一个元组,方法则将第一个元素和x坐标相加,将第二个元素和y相加,并返回一个包含相加结果的心Point对象。

首先需要判断传入的第二个参数的类型与第一个参数类型是否一致,这里需要用到内置函数isinstance,接收一个值和一个类对象(当然也可以换成列表、元组等),如果类型相同则返回True,否则返回False.

然后为每一种情况设置一个方法实现上述效果。

class Point(object):

def __init__(self,x,y):

self.x=x

self.y=y

def print_point(p):

print('(%g,%g)'%(p.x,p.y))

def __str__(self):

return '(%g,%g)'%(self.x,self.y)

def increment(self,other):

return (self.x+other[0]),(self.y+other[1])

def __add__(self,other):

if isinstance(other,Point):

return self.add_point(other)

else:

return increment(self,other)#这里写错了,应该写成return self.increment(other)

def add_point(self,other):

return (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))

---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

in

----> 1 print(blank+(2,3))

in __add__(self, other)

14             return self.add_point(other)

15         else:

---> 16             return increment(self,other)

17     def add_point(self,other):

18         return (self.x+other.x),(self.y+other.y)

NameError: name 'increment' is not defined

报错显示increment没有被定义,去类里面看了下发现在第二种情况的代码写错了,应该用方法而不是函数,将代码修改后

class Point(object):

def __init__(self,x,y):

self.x=x

self.y=y

def print_point(p):

print('(%g,%g)'%(p.x,p.y))

def __str__(self):

return '(%g,%g)'%(self.x,self.y)

def increment(self,other):

return (self.x+other[0]),(self.y+other[1])

def __add__(self,other):

if isinstance(other,Point):

return self.add_point(other)

else:

return self.increment(other)

def add_point(self,other):

return (self.x+other.x),(self.y+other.y)

然后还是报同样的错误,按说明明已经修改成功了,应该返回正确的值,但还是报错,这就说到修改class类时需要重启服务器的问题了,判断标准是我把这段代码复制到另一个页面时是正常返回值,在本页面就一直报错,所以重启了jupyter notebook后就显示正常了。我记得在哪里看到修改class是需要重启服务器的。

3.编写一个叫做Kangaroo的类,有如下方法

一个__init__方法,将属性pouch_contents(口袋中的东西)初始化一个空列表

一个put_in_pouch方法接收任何类型的对象,并将它添加到pouch_contents中

一个__str__方法,返回Kangaroo对象以及口袋中的内容的字符串表达形式。

创建两个Kangaroo对象,将它们赋值给kanga和roo,并将roo添加到kanga的口袋中。

class Kangaroo(object):

def __init__(self,pouch_contents=[]):

self.pouch_contents=pouch_contents

def put_in_pouch(self,a):

self.pouch_contents.append(a)

def __str__(self):

return '%s'%self.pouch_contents

kanga=Kangaroo([1])

roo=Kangaroo([2])

kanga.put_in_pouch(roo)

print(kanga)

这是我看到这个问题想到并写出的代码,但是这个里面有个小的问题,初始化时pouch_contents=[]不具有扩展性,如果修改类的话原来写的都会跟着变,所以在查看答案代码中它有把第一个方法做了下调整:

class Kangaroo(object):

def __init__(self, contents=None):

if contents == None:

contents = []

self.pouch_contents = contents

def put_in_pouch(self,a):

self.pouch_contents.append(a)

def __str__(self):

return '%s'%self.pouch_contents

将contents带一个默认值,如果不传参数时就按默认值处理,如果传入参数可以按传入参数处理,扩展性会好一些。

然后答案代码将第三个方法也有处理,不过和我的不一样

class Kangaroo(object):

def __init__(self, contents=None):

if contents == None:

contents = []

self.pouch_contents = contents

def put_in_pouch(self,a):

self.pouch_contents.append(a)

def __str__(self):

"""return a string representation of this Kangaroo and

the contents of the pouch, with one item per line"""

t = [ object.__str__(self) + ' with pouch contents:' ]

for obj in self.pouch_contents:

s = '   ' + object.__str__(obj)

t.append(s)

return '\n'.join(t)

我基本上能理解这个方法,就是对object.__str__(self)有点疑问,暂时还无法理解,上网查了下发现涉及了一些继承的问题,放在后面学了继承之后再回来看看这个问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值