简体   繁体   中英

__str__ outputs “instance at 0x00E4F558”

This is my first cry for help in this site. I have searched for an answer here, but nothing really clears it for me.

I'm trying to learn Python. I've in the "class" chapter. The following code:

class Character:
    def __init__(self, name, initial_health):
        self.name = name
        self.health = initial_health
        self.inventory = []

    def __str__(self):
        s  = "Name: " + self.name
        s += "| Health: " + str(self.health)
        s += "| Inventory: " + str(self.inventory)
        return s

    def grab(self, item):
        self.inventory.append(item)

me = Character("vic", 37)
me.grab("pencil")
me.grab("paper")
print str(me)

...produces:

Name: vic| Health: 37| Inventory: ['pencil', 'paper']

But the following code, which appears to me pretty similar, prints out the memory locations rather than the variables themselves:

import random
SUITS = ['C', 'S', 'H', 'D']
RANKS = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K']
VALUES = {'A':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':10, 'Q':10, 'K':10}

# define card class
class Card:
    def __init__(self, suit, rank):
        if (suit in SUITS) and (rank in RANKS):
            self.suit = suit
            self.rank = rank
            self.value = self.get_value()
        else:
            print "Invalid card: " + str(suit) + str(rank)
    def __str__(self):
        return str(self.suit) + str(self.rank)
    def get_cardDetails(self):
        return self.suit + self.rank + ": " + str(self.value)
    def get_suit(self):
        return self.suit
    def get_rank(self):
        return self.rank
    def get_value(self):
        value = VALUES[self.rank]
        return value

class Hand:
    def __init__(self, card1, card2):
        self.cardCount = 0
        self.cards = []
        self.cards.append(card1)
        self.cardCount += 1
        self.cards.append(card2)
        self.cardCount += 1
        self.value = self.get_value()
        print "Dealed hand: " + str(self.cards[0]) + str(self.cards[1])
        print "Dealed hand: " + str(self.cards)
    def __iter__(self):
        return iter(self.cards)
    def __str__(self):
        return str(self.cards)
    def get_details(self):
        print "Hand: "
        for each in self.cards:
            print " -" + str(each) + ": " + str(each.value)
        s = "Cards: " + str(self.cardCount) + \
               " | Hand: " + str(self.cards) + \
               " | Total Value: " + str(self.value) + " |"
        return s
    def add_card(self, card):
        self.cards.append(card)
        self.cardCount += 1
        self.value = self.get_value()
        print "Added: " + str(card)
    def get_value(self):
        value = 0
        for each in self.cards:
            value = value + each.value
        return value


c1 = Card("C", "2")
c2 = Card("C", "3")
h = Hand(c1, c2)
print str(h)

Output:

Dealed hand: C2C3
Dealed hand: [<__main__.Card instance at 0x00E4F558>, <__main__.Card instance at 0x00E543C8>]
[<__main__.Card instance at 0x00E4F558>, <__main__.Card instance at 0x00E543C8>]

I'm sure I must be missing something here -I'm just learning this after all. Any help will be appreciated. Thanks in advance. And sorry for the long post.

The __str__ method of a list calls __repr__ on the elements of the list, not __str__ . You can either iterate through the list casting the elements to str yourself, or write a Hand class which subclasses from list and defines __str__ to call __str__ on its elements.

That depends what you are trying to print. In Python if you are printing an object a it is first converted to string by evaluating a.__str__() . If your class has a method __str__ defined, Python uses it. Otherwise it uses the __str__ method from object (in new style classes and in Python 3.x).

Anyway the way the objects are printed depends on how the __str__ method is implemented. If you are evaluating str(els) , where els is a list, then Python actually calls List.__str__(lis) and this function is implemented in such a way that it prints repr of objects contained inside. (And function repr returns by default such output as you see.)

If you want to use the objects str methods, you can write:

[str(el) for el in els]

where els is a list of your objects.

Lists print the repr() of their elements, not the str() . Add:

__repr__ = __str__

to your Card class definition. This will make the repr() of your Card class the same as the str() of it, and lists will print your cards as you expect.

You could instead write the __str__ of Hand to take the str() rather than the repr() of list items.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM