2

'sup guys,

I'm just doing my usual random little programs before my exam within a few days and I decided to write a five card draw poker. Since it's simply for playing a bit with code, I didn't inherit anything from basic classes. My deck contains a list attribute, which has been given the functionality it needs for simple readability and functionality:

import random

from card import Card

class Deck():

    def __init__(self):
        self.cards = self.__generate_cards()
        random.shuffle(self.cards)

    def __str__(self):
        cards_str = ""
        for card in self.cards:
            cards_str += str(card)
        return cards_str

    def __getitem__(self,index):
        return self.cards[index]

    def __generate_cards(self):
        cards = []
        for i in range(4):
            for j in range(13):
                cards.append(Card(i,j+1))
        return cards

    def pop(self,index):
        return self.cards.pop(index)

as you can see, there is no .__iter__ method to be found, which means I can't iterate over a Deck() object right? Python shows me a different story: for some reason the next code results in looping over the card objects in self.cards and actually printing the cards without the need of an iterator:

deck = Deck()
for card in deck:
    print(card)    # cards have a __str__ method

Doesn't make much sense to me, unless it's part of the python magic, giving any object a chance for possible looping. ;p Can anyone show me the light with this one? thanks in advance!

olivier.va
  • 129
  • 1
  • 9
  • 2
    possible duplicate of [Why does defining __getitem__ on a class make it iterable in python?](http://stackoverflow.com/questions/926574/why-does-defining-getitem-on-a-class-make-it-iterable-in-python) – David Robinson Aug 20 '12 at 20:57
  • Point of style, why the double underscore on `__generate_cards`? Name mangling is no more of a way to make something private than single underscore... – Silas Ray Aug 20 '12 at 20:59
  • @sr2222: see [here](http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private). Besides, it's the standard way to do private methods. – David Robinson Aug 20 '12 at 21:00
  • @DavidRobinson I've seen plenty of packages using single underscore for gentlemen's agreement privates (just as name mangled privates are gentleman's agreement too). – Silas Ray Aug 20 '12 at 21:13
  • I'm just following the conventions that I've learned during my courses. Even though 'private methods' in python aren't private to the fullest (still pretty easy to access), it's just 1) conventional reasons 2) helps preventing private method overriding (edit: this is stated in the link above me already :p) – olivier.va Aug 20 '12 at 21:15
  • @sr2222: But why use single over the double? To save a character of typing? – David Robinson Aug 20 '12 at 21:32
  • In my experience, name mangling creates more problems than it solves, especially when you start getting in to more advanced stuff like metaclasses or more complicated inheritance mappings. Of course, as will anything, ymmv. – Silas Ray Aug 20 '12 at 22:25

1 Answers1

2

Why does defining __getitem__ on a class make it iterable in python?

It's a back-compat thing. Having __getitem__ makes it iterable.

Community
  • 1
  • 1
Silas Ray
  • 25,682
  • 5
  • 48
  • 63
  • +1. Do you think this makes the question a duplicate? (The extend to which the question isn't a duplicate is very localized). – David Robinson Aug 20 '12 at 20:56
  • @ sr2222, I guess I should've done more homework :p didn't find much of a connection between `__getitem__` and iterating over an object with a for loop, but your link makes it pretty clear! thanks :). I'm a 3.x python user since I started, so I'm not very up-to-date with the backw-comp features in python. thanks again ! – olivier.va Aug 20 '12 at 21:04