Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Richard Li
Richard Li
9,751 Points

Python Dice Game - Hand Part why not self = super().__init__ in the Hand(list) part?

my questions is that when we __init__ the Hand class, why directly we can use super().__init__? instead of self = super().__init__?

then later how did python know to self is a list if we never assign the attribute to it

Steven Parker
Steven Parker
229,644 Points

I would help in answering your question if you provide a link to the course page you are referring to.

2 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

When a new class is created (or instantiated), the class instance springs to life and is automatically returned to the caller by the __new__ method. The __new__ method calls the __init__ method to initialize any parameters on this instance.

The purpose of the first parameter, self, in all instance methods is to identify which instance the method will be modifying.

The __new__ passes the instance ID it created to the __init__ method through the self parameter.

The super().__init__() automatically passes along the self value it received from the __new__ method.

So as Steven Parker says, the __init__ method only modifies an existing instance. It never creates or returns an instance.

Richard Li
Richard Li
9,751 Points

Thanks for you help!!

here is my code:

class Hand(list):
    def __init__(self, size=0,):
        super().__init__()
        for _ in range(size):
            self.append(die_class())
        self.sort()

I assume __new__ is from the superclass of all-OBJECT, right? So please help me connect the dot here, how did the python use super().__init__() to match a empty list to the instance ID?

Chris Freeman
Chris Freeman
Treehouse Moderator 68,423 Points

The __new__ method is inherented from the list class. The flow is something like:

  • create new Hand instance using
h = Hand()
  • calls Hand() to create new object
  • calls __new__ (inherited from list)
  • __new__ creates new instance with an ID, let’s call it IDx
  • __new__ calls IDx.__init__ which it got from Hand.__init__ (your code). The new instance ID, IDx, is automatically used as the self argument to __init__
  • IDx.__init__ calls super, passing IDx as the self argument, to list.__init__
  • IDx.__init__ runs the for loop
  • IDx.__init__ completes. Control passes back to __new__, which returns the initialized object ID, IDx
  • IDx is then assigned to the variable h

Keep in mind that Python doesn’t pass the actual objects around well calling functions or methods, or when assigning variables. Instead it passes the ID of the object, which is usually its address location in memory.

You can use the built-in id() function to see this value:

>>> h = Hand()
>>> id(h)
4685027912

Note: your values may change due to differing memory ranges assigned upon each new execution of the Python shell by the OS.

Richard Li
Richard Li
9,751 Points

Thank you so much! it is 100% clear to me now!

Steven Parker
Steven Parker
229,644 Points

The __init__ function is called to set things up in a new instance. The new instance already exists, so it's not necessary or desirable to have the function create one. It's also not typical for it to return anything, so it would not be a good idea to expect a return from calling it.

Richard Li
Richard Li
9,751 Points

Thanks for you help!!

I understand what you say. Normally in init there are self.name to create and set attribute but never self alone.

class Hand(list):
    def __init__(self, size=0,):
        super().__init__()
        for _ in range(size):
            self.append(die_class())
        self.sort()

Here is the code, super().init() create an empty list but how did the instance get it?