[Tutor] Methods defined in my class are affecting all the objects at runtime.
Brian Stovall
hoppenmaus at gmail.com
Sat Oct 29 18:13:18 CEST 2011
Thanks for all the wonderful help, everyone!
On 10/29/11, Peter Otten <__peter__ at web.de> wrote:
> 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
>
>
> _______________________________________________
> 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