[Tutor] Methods defined in my class are affecting all the objects at runtime.
Peter Otten
__peter__ at web.de
Sat Oct 29 17:26:02 CEST 2011
Brian Stovall wrote:
> Hello world!
>
> I obviously don't understand something important and basic, but I am
> having trouble figuring it out myself... I am running python v3.2.2 on
> a Win XP machine.
>
> My code:
>
> import card_model
> import random
>
> class Pile:
> """An Object reperesenting a list of 'Card' Objects: could be a
> hand, discard pile, tableau
> or anything really. Has a display_type that is used to clarify
> what kind of display to use, and
> .deal(cards[] , new_pile(Pile Object)) and .shuffle() methods."""
>
> DISPLAY_TYPES = ["STACK", "FAN", "ACCORDION", "CASCADE"]
>
> def __init__(self, cards = [], display_type = "STACK"):
That is a common pitfall: the default values of functions and methods are
evaluated only once. Therefore all Pile instances created without an
explicit cards argument
p = Pile()
end up sharing the same cards list. The idiomatic way to avoid that problem
is a default value of None:
def __init__(self, cards=None, display_type="STACK"):
if cards is None:
cards = [] # no list provided -> make a new one
self.cards = cards
self.display_type = display_type
Note that this problem can only occur with "mutable" types (types whose
internal state can be modified at any time); the default for display_type is
immutable (its state is set once and for all when the object is created) and
thus cannot cause that kind of trouble.
> self.cards = cards
> self.display_type = display_type
>
> def __str__(self):
> return_string = ""
> for i in self.cards:
> return_string = return_string + str(i) + "\n"
Have a look at str.join(). Example:
"\n".join(str(card) for card in self.cards)
> return_string = return_string + str(self.display_type)
> return return_string
>
> def shuffle(self):
> random.shuffle(self.cards)
>
> def add(self, card_list):
> for i in card_list:
> self.cards.append(i)
Have a look at list.extend().
> def deal(self, number_of_cards, position = 0):
> """Deletes the number of cards out of the pile, starting from
> position (default is the top) and returns that list of cards, for
> communication with other piles' .add methods."""
>
> dealt_list = []
> try:
> for i in range(number_of_cards):
> dealt_list.append(self.cards[position])
> del self.cards[position]
Have a look at list.pop() or slices like
cards[position:position+number_of_cards]
> return(dealt_list)
> except IndexError:
> print("Error, out of cards!")
>
> return(None)
>
> I had been testing it with single objects favorably, but when I
> instantiate two Pile objects, methods like .add or .shuffle affect all
> of the Pile objects in memory. At first I thought the objects were all
> initializing to the same space in memory, but it wasn't true. If you
> need to see all my modules or my tester code, I will happily post.
>
> Thanks for helping a rank beginner!
>
> -Brian
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
More information about the Tutor
mailing list