【问题标题】:Python: Can't copy pygame surface objectsPython:无法复制 pygame 表面对象
【发布时间】:2019-04-09 16:28:42
【问题描述】:

我有一堂课:

class personInfo:
    def __init__(self,name,age,height,hairColour,face):
        self.name = name
        self.age = age
        self.height = height 
        self.hairColour = hairColour
        self.face = face

我在这里有几张图片,我使用 pygame 模块加载它们。

yellowFace = pygame.image.load("happy.png")
blueFace = pygame.image.load("sad.png")
redFace = pygame.image.load("angry.png")

我创建了一个包含该类实例的数组。我在这里填充它。

personArray = []
while len(array) != 10:
    personArray.append(personClass("John",32,6,"Blond",yellowFace))

我想将该类的实际变量(姓名、年龄、身高、头发颜色等)存储在一个名为“personStorage”的变量中。但是,我不能让该 var 可变,因为我需要访问该 var 的值并更改它们。这样做不能更改 personArray 中任何实例的值。我该怎么做?

编辑: 我似乎也无法复制此类,因为我收到一个类型错误,上面写着:“无法腌制 pygame.surface 对象”,因为我在该类中有一个表面对象的值。

【问题讨论】:

  • 你的意思是像personStorage = ("John", 32, 6, "Brown"); personClass(*personStorage)这样的吗?
  • 它更像是 personStorage = personArray[2] ,它会为我提供该特定实例的值,以便我可以更改它们。例如,我可以做 personStorage.name = "Rick" 例如。我遇到的问题是 personArray[2] 的名称 var 更改为“Rick”,而不是默认值“John”
  • 所以您基本上需要personInfo 实例的副本,而不仅仅是对它的引用?按照copy 模块的描述实现personInfo.__copy__,然后使用personStorage = copy.copy(personArray[2])。 (deepcopy 可能是必要的,具体取决于您的情况。)
  • 是的,这基本上就是我所需要的。然后我想更改数组中的特定实例。例如 personArray[2] = personStorage。举个例子。
  • 如果您要将修改后的副本分配回同一个插槽,为什么不就地修改原始副本?我只是想弄清楚你真正需要什么

标签: python class copy


【解决方案1】:

如果我明白你想要做什么:

class PersonInfo:
    def __init__(self,name,age,height,hairColour):
        self.name = name
        self.age = age
        self.height = height 
        self.hairColour = hairColour
    def toList(self):
        return [self.name, self.age, self.height, self.hairColour]

顺便说一句,类名的第一个字母总是大写的。

编辑:实现你想要做的事情:

    old = PersonInfo("old", 1, 2, "blue")
    new = PersonInfo(*old.toList())
    new.name = "new"
    print(old.name) #'old'

【讨论】:

  • 这不是我的意思。我的意思是创建一个我可以更改的全新 var,但是,它将从类数组中的特定实例访问它的 var。例如,personStorage = personArray[2]。我想更改 personStorage 的值而不更改 personArray 的值。
  • 好的!我编辑了我的答案,使其符合你想要做的事情。
  • 如果我在那个类中有一个 pygame 表面对象值怎么办?我编辑了原始问题以匹配这个问题。因为使用这种方法,我得到一个 TypeError,上面写着:“can't pickle pygame.Surface objects”
【解决方案2】:

使用复制模块:

函数copy()对任意Python对象的浅拷贝操作。

import copy


class PersonInfo:
    def __init__(self, name, age, height, hair_colour):
        self.name = name
        self.age = age
        self.height = height
        self.hairColour = hair_colour


personArray = []
for x in range(20, 24):
    personArray.append(PersonInfo("John", x, 6, "Brown"))


personStorage = copy.copy(personArray[2])
personStorage.name = "Ana"

print("\rpersonArray[2].name is %s\n"
      "\rpersonStorage.name is %s"
      % (personArray[2].name, personStorage.name))

【讨论】:

    【解决方案3】:

    我已经创建了 setter 和 getter 来获取数据。您也可以创建保存数据的实例的副本。

    from copy import deepcopy
    class PersonInfo:
        def __init__(self,name,age,height,hairColour):
            self.name = name
            self.age = age
            self.height = height 
            self.hairColour = hairColour
    
    x = PersonInfo("Mario",34,1.70,"blue")
    
    print(x.height)  # prints 1.70
    
    x1 = deepcopy(x)
    
    print(x1.age)
    

    【讨论】:

    • 这只是冗长的样板文件,并不能防止 OP 关注的那种无意修改。
    • @chepner 已修复。
    • 好的,现在 getter 和 setter 只是不必要的样板。摆脱它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    相关资源
    最近更新 更多