0

I am using Python 3 and I want to simulate a card game with my Card class below:

class Card:
    def __init__(self, name = "", stars = 0, attack = 0):
        self.name = name
        self.stars = stars
        self.attack = attack

    def setName(self, name):
        self.name = name

    def getName(self):
        return self.name

    def setStars(self, stars):
        self.stars = stars

    def getStars(self):
        return self.stars

    def setAttack(self, attack):
        self.attack = attack

    def getAttack(self):
        return self.attack

    def attack(self, enemyCard):
        print(self.name + "attacked" + enemyCard.getName() + "and did" + self.attack + "damage!")

The following is my driver class:

def main():
    me = Card()
    me.setName("Good")
    me.setStars(99)
    me.setAttack(9000)

    you = Card()
    you.setName("EVIL")
    you.setStars(0)
    you.setAttack(-1)

    me.attack(you)      <-error here

Everything works except at the very last line which is me.attack(you):

TypeError: 'int' object is not callable

I think it may have something to do with my attack method in Card but I don't quite understand why the variable you is seen as an int

  • 9
    Your class has an attribute named `attack` _and_ a function named `attack`. You'll have to rename one of the two. – Aran-Fey Apr 06 '18 at 19:23
  • While you are at it, get rid of all your `get*` and `set*` functions. They don't do anything except wrap simple attribute access, so just access the attributes directly. – chepner Apr 06 '18 at 19:24
  • It's complaining that `me.attack` is an `int`, not a function, so it can't be applied to `you`. Unless you rename the attribute or the method, you'll have to write `Card.attack(me, you)` instead. – chepner Apr 06 '18 at 19:25
  • In addition to @chepner's comment, also see [_What's the pythonic way to use getters and setters?_](https://stackoverflow.com/questions/2627002/whats-the-pythonic-way-to-use-getters-and-setters) – Christian Dean Apr 06 '18 at 19:26
  • @chepner What if some more processing is needed? Getters and Setters are not necessarily bad – Adonis Apr 06 '18 at 19:26
  • 1
    @Adonis use the `property` decorator. See the question I linked to above. – Christian Dean Apr 06 '18 at 19:27
  • 2
    @Adonis The nice thing about properties is that they maintain backwards compatibility with attributes. If existing code uses `me.attack = 3`, then changing `attack` from a simple attribute to a property doesn't require any changes to the existing code. – chepner Apr 06 '18 at 19:31
  • the problem is in your `constructor` and `setAttack` and `getAttack` method, change the name of instance variable different than method name `attack` and things will work – Gaurang Shah Apr 06 '18 at 19:36
  • See also https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/#object-attribute-lookup. – chepner Apr 06 '18 at 19:42

0 Answers0