python自学日记11类和对象

24次阅读

共计 1952 个字符,预计需要花费 5 分钟才能阅读完成。

1. 编写一个函数 move_rectangle, 接受一个 Rectangle 对象和两个值,dx,dy。它应当通过添加 dx 到 corner 的 x 坐标和添加 dy 到 corner 的 y 坐标来改换矩形的位置

因为这个练习涉及了很多前面的例子和练习,如果不写出来可能看不懂,所以把需要涉及的内容先写出来。

首先我们定义一个类型叫做类:

class Point(object):
    '''Represents a point in 2-D space.'''
print(Point)
<class '__main__.Point'>

然后我们建一个矩形的类:

class Rectangle(object):
    '''Represents a rectangle
    attributes:width,height,corner.
    '''
box=Rectangle()
box.width=100.0 #矩形宽度
box.height=200.0 #矩形高度
box.corner=Point() #corner 是 Point 的一个对象,用来指定左下角的定点
box.corner.x=0
box.corner.y=0

然后然后下面是练习的代码,这个函数相对容易,有三个形参,一个是对象,另外两个值作用在 corner 坐标上,结果如下

def move_rectangle(rect,dx,dy):
    rect.corner.x+=dx
    rect.corner.y+=dy
move_rectangle(box,10,20)
print_point(box.corner)
(10,20)

对象是可以复制的,我们可以使用 copy 模块对对象进行复制,不过复制分为浅复制 copy 和深复制 deepcopy

import copy
box2=copy.copy(box)
box2 is box
#box2 == box #也会返回 False 因为 == 对于实例来说的默认行为和 is 是相同的 
False
box2.corner is box.corner #这表明 copy 复制对象本身但不复制内嵌的 Point 对象,称为浅复制 
True

下面是深复制例子

box3=copy.deepcopy(box)# 与浅复制相对,deepcopy 深复制复制对象和内嵌的对象,甚至他们引用的对象以此类推,就是全复制了
box3.corner is box.corner 
False

以上所有的举例和练习都是为了让下面的联系好理解

2. 编写 move_rectangle 的一个版本,它会新建并返回一个 Rectangle 对象,而不是直接修改就有的对象

分解这个问题,不直接修改对象移动首先就需要复制矩形,不能用浅复制的原因是虽然矩形被复制了,但是他们共用一个 corner,所以实际上导致原矩形被移动了,所以需要用深复制,不过需要得出一个新对象,我想可不可以用四个参数,第二个参数作为复制第一个参数,不过需要先做一个简要的实验;

def a(rect,rect1):
    rect1=copy.copy(rect)
a(box,box1)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-33-550f2a30860b> in <module>
      1 def a(rect,rect1):
      2     rect1=copy.copy(rect)
----> 3 a(box,box1)

NameError: name 'box1' is not defined

所以使用四个参数的方法有点问题,如果这个参数之前未被定义会报错,所以只能用三个参数,后面想在函数中复制对象,并将此赋值给一个全局对象,后面发现如果使用了 return 就不需要使用全局对象了

import copy
def move_rectangle_copy(rect,dx,dy):
    #global rect1
    rect1=copy.deepcopy(rect)
    rect1.corner.x+=dx
    rect1.corner.y+=dy
    return rect1
move_rectangle(box,10,20)
print_point(rect1.corner)

结果倒是对了,不过貌似还可以用之前学过的问题识别方法将上面的代码简化,复制对象后面的可以用前面的函数替代:

import copy
def move_rectangle_copy(rect,dx,dy):
    rect1=copy.deepcopy(rect)
    move_rectangle(rect1,dx,dy)
    return rect1
move_rectangle(box,10,20)
print_point(rect1.corner)

这样代码会稍微精简一些。

正文完
 0