macaato
macaato

Reputation: 191

How to increment every time a class instance is called

I am learning more about OOP in Python and I have hit a bit of a road block. Below is my code:

class Player:

    bats = 0
    hit = 0
    freePass = 0
    out = 0
    defenseError = 0

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

        Player.hit+=1
        Player.freePass+=1
        Player.out+=1
        Player.defenseError+=1

#--------------------------------
def main():
    steve = Player("steve")
    steve.hit
    steve.hit
    steve.hit

#--------------------------------
main()

As you can tell, I have created a class that is supposed to increment a counter every time an instance is called in the main function. For example, 'steve.hit' is called three different times, so the hit counter should increment to 3. I have attempted many different ways of approaching this; but every time I try something, instead of counting the three different calls as such, the program will only count the three calls as one. Thank you for any help you can give me

Upvotes: 1

Views: 9026

Answers (2)

carlos_fab
carlos_fab

Reputation: 18

First thing, you need to instantiate you class. This effectively means to go and build an object (Player) based on the plan that you defined in the class. You do that just by declaring a new variable, steve = Player("steve")

The __init__ method is a special method that gets called automatically when you create a new object. Here, your class takes only one argument, name. All other variables like hit are assigned automatically to 0.

If you want to change the value of hit, you should create a function (also known as a method. Then you call this method quite simply with steve.increment_hit().

class Player():
    """Class to represent a player."""
    def __init__(self, name):
        self.name = name
        self.hit = 0
        self.bats = 0
        self.freePass = 0
        self.out = 0
        self.defenseError = 0

    def increment_hit(self):
        """Increase hit count by one when called."""
        self.hit += 1

#  instantiate your class
steve = Player("steve")
print("Hits for '{}' after instantiate your class: {}\n".format(steve.name, steve.hit))

# call the increase_hit method 3 times
for i in range(3):
    steve.increment_hit()
    print("Hits for player {}: {}".format(steve.name, steve.hit))

Try always change the value of variables by calling a method, never by accessing the variable itself directly.

Is better use steve.increment_hit() than accessing class variables directly with steve.hit += 1, for example.

After run the code above, you will get this output:

 Hits for 'steve' after instantiate your class: 0

 Hits for player steve: 1
 Hits for player steve: 2
 Hits for player steve: 3

Upvotes: 0

U13-Forward
U13-Forward

Reputation: 71580

I would prefer the below for calss:

class Player:
    def __init__(self, name):
        self.name = name
        self.bats_ = 0
        self.hit_ = 0
        self.freePass_ = 0
        self.out_ = 0
        self.defenseError_ = 0
    def hit(self):
       self.hit_+=1
    def freePass(self):
       self.freePass_+=1
    def out(self):
       self.out_+=1
    def defenseError(self):
       self.defenseError_+=1

Make self instead of Player, and make functions for them,

Then call it like (see comments):

def main():
    steve = Player("steve") # Create a player
    steve.hit() # add 1 to `hit`
    steve.hit() # add 1 to `hit` again
    steve.hit() # add 1 to `hit` again
    return steve.hit_ # to return, use `_hit` because in `__init__`, it's called `hit_`, which is added always

Now:

print(main())

Outputs:

3

Yey!!, it's as expected.

Or even better @property:

So class would be:

class Player:
    def __init__(self, name):
        self.name = name
        self.bats_ = 0
        self.hit_ = 0
        self.freePass_ = 0
        self.out_ = 0
        self.defenseError_ = 0
    @property
    def hit(self):
       self.hit_+=1
    @property
    def freePass(self):
       self.freePass_+=1
    @property
    def out(self):
       self.out_+=1
    @property
    def defenseError(self):
       self.defenseError_+=1

Then to call it (no need to call just type it without parenthesis):

def main():
    steve = Player("steve")
    steve.hit
    steve.hit
    steve.hit
    return steve.hit_

Now:

print(main())

Outputs:

3

Yey!!, it's as expected.

Upvotes: 4

Related Questions