#๐Ÿ”’ Classes Inheritance Super() method.

302 messages ยท Page 1 of 1 (latest)

strange pollen
#

Hey guys im a little confused in these super() methods , in my example lets say we have the code ( two classes ) :


class Human:
    Species = 'HomoSapiens'
    def __init__(self , name):
        self.name = name

class Animals(Human):
    def __init__(self , animal_name , name):
        super().__init__(name)
        self.animal_name = animal_name

Human1 = Human('Asim')
Animal1 = Animals('Dog')
``` So What i really want to do is to inherit the Human1 Object **name** attribute from the  Human Class. I'm a Beginner so be kind to me. : )
Any help is appreciated.
scarlet pantherBOT
#

@strange pollen

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

hoary stone
strange pollen
#

What do you mean by that ?

hoary stone
#

What is your goal with this Animal class? What does it need a name and an animal name?

strange pollen
#

So this is not the real thing im working on In my real Example There is a Artist Class a Artwork and a Exhibition Class , I want to inherit the Artist name from the Artist class to the Artwork Class.

#

I can provide you that code ?

hoary stone
#

Yes please

#

!paste

scarlet pantherBOT
#
Pasting large amounts of code

If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/

After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.

hoary stone
#

If your classes are Artist, Artwork, and Exhibition though, it doesn't sound like you need inheritance at all

strange pollen
hoary stone
#

I see no reason why Artwork should inherit from Artist

#

They are two completely different concepts

strange pollen
hoary stone
#

Subclasses are meant to be extensions of existing ideas, so you can make something more specific

hoary stone
strange pollen
#

So what i exactly need ?

hoary stone
#
class Artwork:
    
    def __init__(self , title , creation_year , medium , price , creator):
        self.title  = title
        self.creation_year = creation_year
        self.medium = medium
        self.price = price
        self.creator = creator
#

add another parameter for the creator

strange pollen
#

So the Creator Parameter How see the Artist ?

#

a Specific Artist ?

hoary stone
#
artist1 = Artist('Picasso',1920,'France')
artwork1  = Artwork('MonaLisa', 1950 , 'Oil Painting' , 10000 , artist1)
#

yes, you add it as an argument when you create the instance

#

I know the monalisa isn't picasso

#

but the idea remains

strange pollen
#

Yup : )

#

But can you teach me the Super( ) things ?

hoary stone
#

yes, but it's not needed here at all

#

Can you define these terms for me?

Class
Instance
Method

strange pollen
#

Yeah i saw tutorials on it but didnt understood

#

Oh ok

strange pollen
#

A class is a blueprint or a predefined structure for creating multiple objects with the same blueprint , it contains methods and attributes.

#

Instance :

#

A instance is basically the Objects Created by the Class , They can be Parameterized Or Non Parameterized.

#

Method :

#

The Methods are the code in the Class just like function def these can take self , and can also do operations on it. ( dont know how to exactly define xD )

#

@hoary stone

hoary stone
#

A method is just a function, but specifically one that requires an instance to call

#

list.append is a method

#

str.upper is a method

strange pollen
#

Oh Yes

#

In my example ```py
artwork1.discounter()

hoary stone
#

yes exactly

topaz silo
#

WDYM, "can be parametrized or non parametrized"?

strange pollen
#
def __init__(self , name , birth_year , country):
hoary stone
#

I wouldn't necessarily include that as part of its definition

strange pollen
#

Dont it need parameters to create a Object.

hoary stone
#

no

strange pollen
#

Ok

topaz silo
#

nope

hoary stone
#

well in this example it does

#

but classes in general don't need parameters

#
class Dog:

    def bark(self):
        print("woof woof")
#

here I don't even have an __init__

strange pollen
#

Thats why i also said non para.

hoary stone
strange pollen
#

Ok

#

Back to the super() ?

hoary stone
#

Can you give me an example of an instance using my class example above?

hoary stone
strange pollen
#
Dog_Picasso = Dog()
Dog_Picasso.bark()
#

It will return ```py
woof woof

hoary stone
#

yes, but stick to lowercase for variable names

hoary stone
strange pollen
#

: )

hoary stone
#

!e

class Dog:

    def bark(self):
        print("woof woof")

my_dog = Dog()
my_dog.bark()
scarlet pantherBOT
strange pollen
#

Yup

hoary stone
#

Let's make a new kind of Dog by inheriting

#

this is a very tired dog. He likes to take a nap after barking

strange pollen
#

So do i can make it ?

hoary stone
#

!e

class Dog:

    def bark(self):
        print("woof woof")

class TiredDog(Dog):
    pass


my_dog = TiredDog()
my_dog.bark()
scarlet pantherBOT
strange pollen
#

Yup

hoary stone
#

notice how TiredDog is able to call .bark(), even though it doesn't define it

#

TiredDog can access every method from Dog

#

No, the entire class TiredDog inherits from Dog

strange pollen
#

Oh sorry

#

Ok

hoary stone
#

right now TiredDog has no new methods/attributes of its own

#

so it basically behaves identically to a regular Dog

strange pollen
#

Yup the parent class cannot access the child class but child can access the parent

hoary stone
#

yes, always

#

the child class is the same as the parent PLUS more

strange pollen
#

the default init of parent always run if child has no constructor

hoary stone
#

yes

#

a child class inherits all the attributes of its parent

#

which includes __init__

strange pollen
#

Yup.

hoary stone
#

!e

class Dog:

    def bark(self):
        print("woof woof")


class TiredDog(Dog):
    
    def bark(self):
        print("*falls asleep*")


my_dog = TiredDog()
my_dog.bark()
scarlet pantherBOT
hoary stone
#

have a look at this though

#

if a child class defines a method with the same name as the parent, then it takes priority

#

the parent and child both have a bark method

#

so when the child calls bark, it uses its own definition instead of the parent's

strange pollen
#

Yes i understand everything till now.

hoary stone
#

Ok great

#

but, very often when we inherit, we want to keep the original behaviour of the parent's method

#

but we also want to add more functionality

#

I want the TiredDog to bark the same way as a regular dog and then fall asleep

#

I could just do this

#
class TiredDog(Dog):
    
    def bark(self):
        print("woof woof")
        print("*falls asleep*")
strange pollen
#

Yeah ?

hoary stone
#

but if I change the way that the regular Dog barks, then I have to change this too

strange pollen
#

Yeah so we will do inherit the changes from the Dog class ?

hoary stone
#

well, this is where super comes in

#

we can use super to access the parent class's definitions/methods

#

!e

class Dog:

    def bark(self):
        print("woof woof")


class TiredDog(Dog):
    
    def bark(self):
        super().bark()
        print("*falls asleep*")


my_dog = TiredDog()
my_dog.bark()
strange pollen
#

Yes .

scarlet pantherBOT
hoary stone
#

when I call super().bark(), it calls the original bark that Dog defined

strange pollen
#

Yup so it can access methods.

hoary stone
#

that's all there is to it

#

super lets you access the method that might have just been otherwise overwritten

strange pollen
#

The super has parameters ? super ( parameter ) ?

hoary stone
#

no

strange pollen
#

We can access ```py
init

hoary stone
#

yes, it's a method

#

it's not special just because it's __init__

#

it's a method, just like bark is a method

strange pollen
#

or its just variable assign ?

hoary stone
#

if the parent class sets it up, then you don't have to

strange pollen
#

Ok like it only has this to learn ?

hoary stone
#
class Dog:

    def __init__(self, colour):
        self.colour = colour


class TiredDog(Dog):
    pass


my_dog = Dog("Brown")
tired_dog = TiredDog("White")
#

let's look at an example with init

strange pollen
#

what about parameterized methods ?

#

Oh ok

hoary stone
#

because TiredDog inherits Dog, it now behaves the exact same (since we haven't changed anything)

#

to create an instance of Dog or TiredDog, we must give it a colour

#

what kind of attribute do you think TiredDog should have? Lets define it's __init__

strange pollen
#

So we should create the color of it too ? maybe its weakness level ?

hoary stone
#

yeah, maybe how tired it is

#

or if it's awake

#

or whether it snores

#

it doesn't really matter, it's just a chance to be creative ๐Ÿ™‚

strange pollen
#

Yes : )

hoary stone
#

ok, let's do a boolean for whether or not it snores

#

def __init__(self, colour, snores):

#

remember it still needs the colour

#

because Dog needs colour too

strange pollen
#

Ok

hoary stone
#
class TiredDog(Dog):
    
    def __init__(self, colour, snores):
        super().__init__(colour)
        self.snores = snores
#

that means we pass the colour parameter to the super call of __init__, and then we create a new attribute for snores

strange pollen
#

Yes we are inheriting the color ?

hoary stone
#

yes, because Dog's __init__ creates the self.colour attribute

#

so by calling super().__init__(colour), we're telling TiredDog to create whatever attributes Dog creates

strange pollen
#

OH OK

hoary stone
#
class RedDog(Dog):

    def __init__(self):
        super().__init__("Red")
#

I could do this if I wanted

#

this dog is always Red

#

no parameter required

strange pollen
#

So we are giving the __init__ method a parameter " Red " ?

hoary stone
#

yes, of the parent class

strange pollen
#

Ok.

hoary stone
#

!e

import random

class Dog:

    def __init__(self, colour):
        self.colour = colour


class RandomColourDog(Dog):
    colours = ['brown', 'red', 'white', 'grey', 'black']

    def __init__(self):
        rand_colour = random.choice(RandomColourDog.colours)
        super().__init__(rand_colour)



dog = RandomColourDog()
print(dog.colour)
scarlet pantherBOT
strange pollen
#

Maybe I was thinking a lot of about it but its simple as that

hoary stone
#

you can do whatever you want, as long as you call the parent's init correctly

#

it's entirely up to you as the creator of the class to come up with what features it should have

strange pollen
#

Now i understand the thing , these things cannot be learned through premade videos , you are indeed a great teacher !

hoary stone
#

they definitely can be learned from videos

#

but usually people start with __init__ to explain super

strange pollen
#

They can be , but confusions...

hoary stone
#

and that is very often where it will be used

#

but I think explaining it with a separate method is simpler to understand

#
class OtherDog(Dog):

    def __init__(*args, **kwargs):
        super().__init__(*args, **kwargs)
#

you'll likely see this quite commonly

strange pollen
#

What the heck is this .... I have a lot to learn.

hoary stone
#

have you seen args or kwargs?

strange pollen
#

Nope not until now ..

hoary stone
#

let's say I wanted a function that could take unlimited arguments

strange pollen
#

Unlimited ?

#

Ok

hoary stone
#
def foo(x, y)
#

if I define this, then the function expects 2 argumments

#
def foo(x, y, z)
#

this expects 3 arguments

strange pollen
#

Yup

hoary stone
#

it only works with 3. No less, no more

#
def foo(*args)
#

if I do this, then the function can receive any number of arguments

#

the name args isn't necessarily important. What's important is the * in front

#

but args is common python convention

#

def foo(*unlimited)

#

this works the same

strange pollen
#

What we will do with all of these args ? how we will handle them ?

hoary stone
#

that's entirely up to you

#

ever used print?

strange pollen
#

Is it a question ?

hoary stone
#

!e

print("a")
print("a", "b", "c", "d")
scarlet pantherBOT
hoary stone
#

print is a function with unlimited args

strange pollen
#

Ohhh So it can take many arguments.

hoary stone
#

!e

def itemizer(*args):
    for i, item in enumerate(args, 1):
        print(f'{i}. {item}')


itemizer("Milk", "Bread", "Eggs")
scarlet pantherBOT
hoary stone
strange pollen
#

so kwargs is also this ?

#

*kwargs

hoary stone
#
def bar(**kwargs):
#

kwargs is "key word arguments"

strange pollen
#

Why it has double ** ?

hoary stone
#

because it handles keyword arguments

strange pollen
#

So what are those ?

hoary stone
#

!e

def menu_maker(**kwargs):
    print(kwargs)


menu_maker(burger=10.99, fries=3.99, drink=1.99)
scarlet pantherBOT
hoary stone
#

when you call a function using keywords instead of positional

#

again, just like with print

#

print works with sep and end

#

those are kwargs for print

strange pollen
#

Yeah keyword arguments ...

#

I remembered

#

it returns a { } ?

hoary stone
#

now, we can also use this when calling a function

strange pollen
#

*print

hoary stone
strange pollen
#

So we can use both of them ?

hoary stone
#

1 sec

strange pollen
#

Ok.

hoary stone
#

!e

def make_square(x, y):
    print('.' * x)
    for _ in range(y):
        print(f'.{" ":^{x-2}}.')
    print('.' * x)

make_square(3, 5)

scarlet pantherBOT
hoary stone
#

have a look at this function

#

don't worry too much about the code inside, but it makes a box with a width and height

#

let's say I had these values in a list

#
size = [5, 5]
#

I can't call the function like this

make_square(size)
#

make_square expects two arguments, but a list is only 1

#

even though it contains 2 values

strange pollen
#

Ok ...

hoary stone
#
size = [5, 5]
make_square(*size)
#

we can call the function like this

#

this is called "unpacking"

#

it takes the values from the list, and calls the function using the inner values

strange pollen
#

So it takes the list unpack it and take the arguments inside it..

hoary stone
#

so index 0 of the list becomes the first argument, and index 1 becomes the second argument

#

yes exactly

#

!e

print(*range(10), sep='-')
scarlet pantherBOT
hoary stone
#

we can do this anywhere really

#

!e

data = [*range(5), *range(95, 101)]
print(data)
scarlet pantherBOT
strange pollen
#

Ok i didn't understood the megamind code but i understood the concept.

hoary stone
#

megamind code?

strange pollen
#
    print('.' * x)
    for _ in range(y):
        print(f'.{" ":^{x-2}}.')
hoary stone
#

ahh yeah

strange pollen
#

it goes over my mind

hoary stone
#

don't worry about that

#

I just wanted a function that did something with 2 arguments

strange pollen
#

and you gave a super easy function

hoary stone
#

we can do a very similar thing with dicts

#
size = {'x': 8, 'y': 3}
#

if I have a dict, and the keys of the dict are the same as the parameter names of the function, then I can unpack using **

#

!e

def make_square(x, y):
    print('.' * x)
    for _ in range(y):
        print(f'.{" ":^{x-2}}.')
    print('.' * x)


size = {'x': 8, 'y': 3}
make_square(**size)
scarlet pantherBOT
strange pollen
#

Bruh , i am just getting more confused..

hoary stone
#

Do you understand dicts?

strange pollen
#

Yes ... but i want to sleep rn.

#

xD

hoary stone
#

without **, I would have to do this instead

#
def make_square(x, y):
    print('.' * x)
    for _ in range(y - 2):
        print(f'.{" ":^{x-2}}.')
    print('.' * x)


size = {'x': 8, 'y': 3}
make_square(size['x'], size['y'])
#

I would need to access each value individually

#

but ** is a very nice shortcut. It automatically looks for the x and y key and places them as arguments

strange pollen
#

Yeah i can see that.

#

tysm

#

now i know the ** and * ,

hoary stone
#
class OtherDog(Dog):

    def __init__(*args, **kwargs):
        super().__init__(*args, **kwargs)
#

so back to this example

#

we can use this when we want our child class __init__ to behave the exact same way as the parent

#

and we don't want to bother specifying the exact arguments

strange pollen
#

Oh thats a pretty shortcut.

hoary stone
#

yeah, if a class has 5 different parameters, instead of typing them out, I would just do this

#

Have you learned any GUI yet?

#

tkinter or pyside?

strange pollen
#

Tkinter mainly..

#

And i have alot of command in it too

hoary stone
#

I can inherit from tkinter widgets to make custom widgets

#

if I wanted a red button, I could do this

#
import tkinter as tk


class RedButton(tk.Button):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self['bg'] = 'red'
#

I want it to behave the exact same as a regular button, but I want it red

#
import tkinter as tk


class RedButton(tk.Button):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self['bg'] = 'red'


root = tk.Tk()

btn = RedButton(text='Hello World')
btn.pack()

root.mainloop()
strange pollen
#

It is vast bro , damn

hoary stone
strange pollen
#

we could just done bg

hoary stone
#

see how I can still use the text='Hello World'?

strange pollen
#

or fg

hoary stone
#

because it inherits from tk.Button

strange pollen
#

Yup.

hoary stone
# strange pollen or fg

yes, but what if I wanted to add more special functionality? Maybe I want it to blink 3 times when I click it

#

that would be annoying to add code that does that for each button

#

but instead, I can keep all that code in my own RedButton class

strange pollen
#

Now i see the use of OOP and classes. somehwere

#

thanks for teaching me today

hoary stone
#

I use it everywhere in GUI, and it's where I really started to see the power of inheritance

strange pollen
#

I dont want to be stuck at tkinter so i will learn pyside too ! Ok now i am going to sleep Bye

#

!close

scarlet pantherBOT
#
Python help channel closed with !close

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.