0

I have a class:

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

I have several images here that I load in using the pygame module.

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

I created an array that holds instances of that class. Here I am populating it.

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

I would like to store the actual variables of that class (name, age height,hairColour, etc) in a variable I will call "personStorage". However, I can't have that var be mutatable since I need to access that var's values and change them. Doing this can't change the values of any instances inside the personArray. How would I do this?

EDIT: I also can't seem to be able to Copy this class because I get a type error that says: "can't pickle pygame.surface objects" since I have a value of a surface object within that class.

7
  • Do you mean something like personStorage = ("John", 32, 6, "Brown"); personClass(*personStorage)? Commented Apr 9, 2019 at 16:31
  • It would be more like personStorage = personArray[2] which would give me the values of what that specific instance has so I can then change them. For example I could do personStorage.name = "Rick" for example. The problem I have is that personArray[2]'s name var is changed to "Rick", instead of the default value of "John" Commented Apr 9, 2019 at 16:33
  • 1
    So you basically need a copy of the personInfo instance, not just a reference to it? Implement personInfo.__copy__ as described by the copy module, then use personStorage = copy.copy(personArray[2]). (deepcopy might be necessary, depending on your circumstances.) Commented Apr 9, 2019 at 16:41
  • Yes, that's essentially what I need. Then I would like to change a particular instance in the array. For example personArray[2] = personStorage. Just as an example. Commented Apr 9, 2019 at 16:44
  • If you are going to assign the modified copy back to the same slot, why not just modify the original in-place? I'm just trying to be clear about what it is you actually need. Commented Apr 9, 2019 at 16:44

3 Answers 3

1

If I understood what you're trying to do :

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]

By the way, class names' first letter is always uppercase.

EDIT : To achieve what you're trying to do :

    old = PersonInfo("old", 1, 2, "blue")
    new = PersonInfo(*old.toList())
    new.name = "new"
    print(old.name) #'old'
Sign up to request clarification or add additional context in comments.

3 Comments

That's not exactly what I meant. I meant creating an entirely new var that I could change, however, it's vars would be accessed from a particular instance in the class array. For example, personStorage = personArray[2]. I want to change the values that personStorage has without changing the values of personArray.
OK ! I edited my answer so it matches what you're trying to do.
What if I have a pygame surface object value in that class? I edited the original question to match this problem. Because using this method I am getting a TypeError that says: "can't pickle pygame.Surface objects"
0

Use the copy module:

The function copy() shallow copy operation on arbitrary Python objects.

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

Comments

0

I have created setters and getters to get the data.Also you can create a copy of the instance that holds the data.

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)

3 Comments

This is just verbose boilerplate that doesn't prevent the kind of inadvertent modifications the OP is concerned about.
@chepner fixed.
OK, now the getters and setters are just unnecessary boilerplate. Get rid of them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.