-5

So i have this class

class Character(object):
    def __init__(self):
        self.NAME = ''
        self.life = 50

I also have this list

 players = ["red","green","blue","yellow"]

I'm trying to make each "player" become a Character and this is what I did

for player in players:
    player = Character()

Now when i go

print(red.life)    #or if i try
print("red".life)    #why doesn't it work?
# for some reason it uses player as object for the
# class but I want the element of the list to be used!     
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
  • What do you believe the line `print("red".life)` does? – Greg Hilston Nov 22 '17 at 15:54
  • Possible duplicate of [Using a string variable as a variable name](https://stackoverflow.com/questions/11553721/using-a-string-variable-as-a-variable-name) – Brad Solomon Nov 22 '17 at 15:56
  • 2
    You need to pass each element of the list as an argument to `__init__`; the string `"red"` is not, and cannot be, an instance of `Character`. `players = [Character(color) for color in ["red", "green", "blue", "yellow"]`. – chepner Nov 22 '17 at 15:56
  • I thought strings could be used as variable for object instances so I thought `print("red".life)` would have given me player red's life! @Greg Hilston – Samuel Greenfield Nov 22 '17 at 17:04
  • Understood. That's what is actually happening. You're asking the string "red" to provide you with the property life, which it doesn't have. – Greg Hilston Nov 22 '17 at 17:05

4 Answers4

3

It would work by putting players into a dict:

class Character(object):
    def __init__(self):
        self.NAME = ''
        self.life = 50

players = ["red","green","blue","yellow"]
dict_players = {}

for player in players:
    dict_players[player] = Character()

However, printing would only work if you create a __str__ method for your class.

mrCarnivore
  • 4,638
  • 2
  • 12
  • 29
1

You have a list of strings, and "red".life is attempting to call a member variable life, which string objects do not contain. Instead, create separate class instances:

class Character(object):
   def __init__(self):
      self.NAME = ''
      self.life = 50

red = Character()
green = Character()
...

Then, you can call life:

print(red.life)
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
  • I don't want to do that because I don't know how many players will be playing, with the list if someone isn't playing I can just remove him from the list. – Samuel Greenfield Nov 22 '17 at 17:05
1

This:

for player in players:
    player = Character()

will create a new Character instance for each item in players (not using the item itself) and assign it to the player variable (each time ovverridding the previous assignment). This won't of course change anything to your players list. After the loop is terminated, you get one single Character() instance bound to the player variable, and that's all. IOW, you'd get the same practical result replacing the loop with a single:

player = Character()

but it won't obviously be of any use.

print(red.life)

Where have you defined a variable named red ?

or if i try print("red".life)

"red" is a string. A string has no attribute life.

for some reason it uses player as object for the class but I want the element of the list to be used!

The "elements of the list" (I assume you mean the players list) are strings too. If you want to get a list of Character instances instead, you can get it that what:

class Character(object):
    def __init__(self, name):
        self.name = name
        self.life = 50

playernames = ["red", "green", "blue", "42"]
players = [Character(name) for name in playernames]

but that will still not create any variables named red, green etc, just a list of Character instances.

If you want to be able to retrieve specific Character instances, you will either need to explicitly create variables or use a dict. Creating variables:

red = Character("red")
yellow = Character("yellow")
# etc

but this means all your characters are hardcoded - you cannot have more or less players nor name them differently etc.

Using a dict:

playernames = ["red", "green", "blue", "42"]
players = {name:Character(name) for name in playernames}

print(players["red"].life)
print(players["green"].life)
# etc
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • Is there no way of turning a string into a "soon to be variable?" I tried using eval(player) = Character() why didn't it work? – Samuel Greenfield Nov 22 '17 at 16:52
  • eval doesn't work that way - but anyway if you don't know beforehand how many players you have using a dict is the only sane solution. How would you know which variables have been defined else? – bruno desthuilliers Nov 22 '17 at 17:52
0

Thanks everyone, I tried to understand all of your answers and made it work, It's for a game I'm trying to make and it's my first time doing something so complicated, my coding is a mess and it has 0 readability. For now I have only made this character creator and world map creator, the map is made of various tiles I will give names to (like shop, river, jungle), each name will have special properties. I have made it possible for the characters to spawn and move around and I will now make something that figures out on what type of tile the Character is, sadly I'm having a hard time figuring out how to give every tile different coordinates. I'm very grateful.