Vin Breau
Vin Breau

Reputation: 279

Why does this script print an extraneous 'none' in the output

I've written a simple script to help me better understand using classes. It generates a random character for a game. I defined the object and then call a function on that object that prints out the generated character. At the end of the printed block, there is an extraneous "None" that I'm not sure where it's coming from nor why it's being printed. Here's the sample output:

ted
Strength  : 20
Dexterity : 17
Hit Points: 100
Aura      : 100
Weapon    :  
Spell     :  
Item      :  
Element   :  
--------------------
None

In my code, the last line of player.stats() is print "-" * 20 which is displayed right above "None". Here's the code that defines the object:

class Player(object):

def __init__(self, name):
    self.name = name
    self.strength = randint(15, 20)
    self.dexterity = randint(15, 20)
    self.hit_points = 100
    self.aura = 100
    self.weapon = " "
    self.spell = " "
    self.item = " "
    self.element = " "

def stats(self):
    print "\n"
    print self.name
    print "Strength  : %d" % self.strength
    print "Dexterity : %d" % self.dexterity
    print "Hit Points: %d" % self.hit_points
    print "Aura      : %d" % self.aura
    print "Weapon    : %s" % self.weapon
    print "Spell      : %s" % self.spell
    print "Item      : %s" % self.item
    print "Element   : %s" % self.element
    print "-" * 20

The object is then instanced using this:

name = raw_input("Name your character: ")

player = Player(name)
print player.stats()

The complete code can be read here at Pastebin if necessary.

Upvotes: 1

Views: 1670

Answers (3)

Eric
Eric

Reputation: 97565

print player.stats()

Is the culprit. player.stats() == None

You want just:

player.stats()

You'd do better to name your function player.printStats().


Another option would be to make it return a string:

def stats(self):
    return '\n'.join([
        self.name
        "Strength  : %d" % self.strength,
        "Dexterity : %d" % self.dexterity,
        "Hit Points: %d" % self.hit_points,
        "Aura      : %d" % self.aura,
        "Weapon    : %s" % self.weapon,
        "Spell     : %s" % self.spell,
        "Item      : %s" % self.item,
        "Element   : %s" % self.element,
        "-" * 20
    ])

And then print player.stats() would behave as expected

Upvotes: 5

David Heffernan
David Heffernan

Reputation: 612794

The stats() method does not return anything. A function that doesn't return anything evaluates to None. Which is what you print.

So, don't print the return value of the function. Just call it. Now, you should rename the function as printStats() to make it clear what it does. And then just call it like this:

def printStats(self):
    ....

player = Player(name)
player.printStats()

Naming is a really important part of programming. A slightly poor choice of name often leads to confusion like this.

Upvotes: 3

Martijn Pieters
Martijn Pieters

Reputation: 1121346

You print the return value of player.stats():

print player.stats()

but the .stats() method does not have a return statement. The default return value of any function or method in python is None, if no return statement has been given:

>>> def foo():
...     pass
...
>>> print foo()
None

Either remove the print before the method call, or have stats() return a string to print instead of doing all the printing in the method.

Upvotes: 2

Related Questions