Home > other >  Add element to list in class
Add element to list in class

Time:08-26

I'm still wrestling with classes. Instead of using the classic employees in a company or car example, I've decided to create a simple game character. So far so good, only I'm having trouble adding to an item to a list which is a class.

class Player():
  def __init__(self, name, items):
    self.name   = name
    self.items  = items

# initialize character
player = Player("Joey", 
  ["movie stub", "keys", "army man"])


print(player.items)
# >> ['movie stub', 'keys', 'army man'] # this is fine

Now I'd like to add an item to the player character.

player.items.push("a rock")
# AttributeError: 'list' object has no attribute 'push'

I try using push - only that results in an attribute error. So I add a simple helper class:

# helper class
class List(list):
  def push(self, x):
    self.append(x)

player.items = List(["a rock"])

Yay! no errors...

print(player.items)
>> ['a rock']

Only instead of appending, it's replaced the list, which is not what I'm after.

Any ideas where I'm going wrong?

CodePudding user response:

You should add push function inside the class itself

class Player():
  def __init__(self, name, items):
    self.name   = name
    self.items  = items

  def push(self, x):
    self.items.append(x)

  def print(self):
    print(self.name,": ",self.items)


# initialize character
player = Player("Joey", 
  ["movie stub", "keys", "army man"])

adding item to the list

player.push("a rock")

printing

player.print()

output

Joey : ['movie stub', 'keys', 'army man', 'a rock']

CodePudding user response:

To be fair you're complicating things. Just made method in class, which add things to your list and you're good to go

class Player():
  def __init__(self, name, items):
    self.name   = name
    self.items  = items
  def add_item(item):
    self.items.append(item)

With this

# helper class
class List(list):
  def push(self, x):
    self.append(x)

player.items = List(["a rock"])

you weren't even passing list you wanted to attach item. So to make your helper work(you do not need it, method in Player is good enough, but I want to show it anyway, because you asked for it)

class List():
  def push(self, list, x):
    list.append(x)

my advise is to put method in class player to append there items

CodePudding user response:

If you don't want to replace it, don't replace it? There is nothing special about the name push, and you never called it, so append never occurred, you just replaced the original list with your unnecessary List subclass.

If you must be able to call push instead of append, convert to your List subclass on construction, so it stores a push friendly list from the get-go:

class List(list):
  def push(self, x):
    self.append(x)

class Player():
  def __init__(self, name, items):
    self.name   = name
    self.items  = List(items)

Now you can just do:

player = Player("Joey", 
                ["movie stub", "keys", "army man"])

player.items.push("a rock")

and it just works. As a side-benefit, it is now shallow-copying the list provided by the caller, so change's made to the caller's list don't retroactively change the instance's attribute's contents, nor vice-versa.

CodePudding user response:

You need to take a more complete OOP approach by encapsulating data and functionality within your class. Something like this:

class Player():
    def __init__(self, name, items):
        self._name = name
        self._items = items
    def push(self, item):
        self._items.append(item)
    def __repr__(self):
        return f'{self._name=}, {self._items=}'
    def __str__(self):
        return f'Name={self._name}, Items={", ".join(self._items)}'

player = Player("Joey", ["movie stub", "keys", "army man"])
print(player)
player.push('a rock')
print(player)

Output:

Name=Joey, Items=movie stub, keys, army man
Name=Joey, Items=movie stub, keys, army man, a rock
  • Related