1

All of the python I know, is entirely self taught, but my goal is to of course try to learn what is best practice/ common convention and try to understand why.

I've only recently dug more into OOP, so in efforts to practice OOP, I wrote a blackjack game as I've heard that's a decent quick project to learn a lot of OOP concepts.

The full program can be found here(GitHub): my blackjack game if needed for context (vs just posting the entirety here)

but I'm struggling to understand exactly what super()__init() does, and if its preferable compared to how I used subclasses: for simplicity take just the following two: Deck and MultiDeck which is a subclass of Deck
The following is a snipet from the game:

import collections
import random
import time 

Card = collections.namedtuple('Card', ['value', 'suit'])


class Deck:

    values = [str(v) for v in range(2, 11)] + list('JQKA')
    suits = "Spades Diamonds Hearts Clubs".split()
    suit_symbols = ['♠','♦','♥','♣']

    def __init__(self):
        self.cards = [Card(value, suit) for suit in self.suits for value in self.values]

    def __repr__(self):
        deck_cards = "Deck()\n"
        for card in self.cards:
            deck_cards += f"({card.value}-{card.suit})"
        return deck_cards

    def __len__(self):
        return len(self.cards)

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

    def shuffle(self):
        random.shuffle(self.cards)

    def draw_card(self):
        return self.cards.pop()

    def reset(self):
        self.cards = [Card(value, suit) for suit in self.suits for value in self.values]

class MultiDeck(Deck):

    def __init__(self, num_decks):
        Deck.__init__(self)
        self.values = Deck.values * num_decks

    # reshuffle when deck is < 50% length
    def is_shuffle_time(self, num_decks):
        return  len(self) < (len(MultiDeck(num_decks))/2)

    def shuffle_time(self):
        print("Reshuffling the Deck...\n")
        time.sleep(1)
        print("Reshuffling the Deck...\n")
        time.sleep(1)
        print("Reshuffling the Deck...\n")
        time.sleep(1)
        self.reset()
        self.shuffle()

Contrast that to Below: which would be the better way: for one, should super() be declared in the superclass Deck or left out? I've stumbled upon a lot of seemingly different answers (but its possible that might be a result of python 3 compared to older versions)
Is it better to instead define MultiDeck like:

class MultiDeck(Deck):

    def __init__(self, num_decks):
        super().__init__()
        self.values = super().values * num_decks   

and on that last line, in initializing self.values is it better to use Deck.values or super().values

If using super() is in fact better practice, what advantage or added benefit does super().__init() provide. and is writing it like Deck.__init__(self) more frowned upon (if so, why?)
I hope I even used it correctly, for example purposes...from what I've read that seemed to be the way to use super(), but please correct me if not.
Thank you for any input in advance.

  • Does this answer your question? [Understanding Python super() with \_\_init\_\_() methods](https://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods) – de_classified Jun 05 '20 at 04:00
  • @FishingCode it does to a degree. thankyou. Though I may have to learn a bit more about MRO. Is it reasonable to say, that super() is very beneficial when a class has many subclasses (whereas my code having one subclass its less obvious what the advantage is), does it essentially allow for a far more fluid way to pass down inheritance? without the need to write the actual name of the class, but rather use super, I'd imagine that's advantageous - vs manually renaming all subclasses if the superclass was renamed: tho please correct me. are there additional benefits to the one's I thought up? – Zach Sonnenblick Jun 05 '20 at 04:14
  • 1
    .. [Super considered super!](https://www.youtube.com/watch?v=EiOglTERPEo) - video – wwii Jun 05 '20 at 04:22
  • 1
    `super()` is more advantageous in the case where you have several classes that need to achieve multiple things, essentially you're gaining multiple inheritance with the use of `super()`. It's beneficial when re-writting what the "parent" class is doing thus it does the lookup from the help of the parent class. Your idea sounds about right, in that if you do not see a case where you don't see a `super()` then no need of it, where ever you can apply the DRY approach, is what one should be aiming for in terms of code quality. – de_classified Jun 05 '20 at 04:28
  • this [example](https://appdividend.com/2019/01/22/python-super-function-example-super-method-tutorial/) does a great job, in terms of explaining `super()` without confusing the concept off it too much. – de_classified Jun 05 '20 at 04:30
  • 1
    @FishingCode ty. was helpful. wasn't until multi-inheritance was mentioned that it became more obv as to the benefits (funny enough, the article you linked, didn't use super() in example for that), but I found [this example](https://www.datacamp.com/community/tutorials/super-multiple-inheritance-diamond-problem) . but I can certainly see how it can be useful- and only needing one super() call - as order is built into its MRO? if I understood. but thanks again – Zach Sonnenblick Jun 05 '20 at 05:01

0 Answers0