Python—如何在不使用deepcopy的情况下复制对象(这样它就不会引用旧对象)?
我有以下代码:Python—如何在不使用deepcopy的情况下复制对象(这样它就不会引用旧对象)?,python,reference,copy,Python,Reference,Copy,我有以下代码: import pygame import block as b import constants as c import copy def walls(): walls_list = [] wall_proto = b.Wall(c.WHITE, 40, 40, 20, 80) wall = copy.copy(wall_proto) wall.rect_x = 50 print wall_proto.rect_x print w
import pygame
import block as b
import constants as c
import copy
def walls():
walls_list = []
wall_proto = b.Wall(c.WHITE, 40, 40, 20, 80)
wall = copy.copy(wall_proto)
wall.rect_x = 50
print wall_proto.rect_x
print wall.rect_x
walls()
印刷品:
50
50
但我想把它打印出来
40
50
我想在我的游戏中创造各种各样的“墙”。这些墙可能有很多相似的数据,但也有些不同。所以我想有一些墙对象,可以用来复制,然后在不同的墙上设置不同的属性。若我使用简单复制,那个么若我更改了复制对象中的任何内容,所有其他对象也会更改该值。我可以用deepcopy,但速度很慢。是否有比deepcopy更好的解决方案
更新
按要求的墙体等级:
class Wall(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#to get/set values
self._width = width
self._height = height
@property
def rect_x(self):
return self.rect.x
@property
def rect_y(self):
return self.rect.y
@property
def width(self):
return self._width
@property
def height(self):
return self._height
@rect_x.setter
def rect_x(self, value):
self.rect.x = value
@rect_y.setter
def rect_x(self, value):
self.rect.y = value
@width.setter
def width(self, value):
self._width = value
@height.setter
def height(self, value):
self._height = value
如果它是一个简单的列表(没有任何可变对象),您可以使用:list[:]或Dict.copy()我会这样做:
wall=
关键字arg添加到wall构造函数李>
wall
,请将值复制到新实例中,然后根据其他参数进行设置。像这样:
class Wall(pygame.sprite.Sprite):
def __init__(self, color=None, x=None, y=None, width=None, height=None, wall=None):
pygame.sprite.Sprite.__init__(self)
# check parameters are valid
assert any([color and x and y and width, wall]), "invalid arguments"
# assign parameters from given wall or parameters
x = x or wall.rect_x
y = y or wall.rect_y
color = color or wall.color
height = height or wall.height
width = width or wall.width
...
然后您可以编写如下代码:
wall1 = Wall(c.WHITE, 40, 40, 20, 80)
wall2 = Wall(color=c.BLUE, wall=wall1)
归根结底,你不应该这样做。考虑一下,制作一个“代码>类方法< /COD>”,它将同时定义整个墙的范围。类似于
class Wall(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
# since your properties are only getters and setters, don't use them
self.width = width
self.height = height
@classmethod
def make_walls(cls, color, coords):
"""Makes a grouping of walls of a specified color, given
a list of (x, y, width, height) tuples"""
list_of_walls = []
for details in coords:
x, y, width, height = details
wall = cls(color, x, y, width, height)
list_of_walls.append(wall)
return list_of_walls
# or MUCH less clear:
# return [cls(color, *details) for details in coords)]
然后,您可以通过以下操作制作任何您喜欢的墙:
wall_locations = [
(1, 1, 1, 1),
(1, 2, 1, 1),
(1, 3, 1, 1),
(1, 4, 1, 1),
... ]
new_walls = b.Wall.make_walls(c.WHITE, wall_locations)
为什么您不喜欢使用
deepcopy
?因为它很慢。如果我只依赖deepcopy,以后可能会降低性能。因此,我希望有一些其他的解决方案,可能会有更好的性能。你能展示一下墙的定义,或者更好地创建一个墙吗?显而易见的定义不应该导致你看到的行为。请问wall\u proto
的性质是什么?你为什么不写wall=b.wall(c.WHITE,50,40,20,80)
?第二个参数是50而不是40。但即使是相同的,我认为名为wall
的实例与名为wall\u proto
的实例将是不同的对象。酷,我自己也做了类似的事情:)