**kwargs in __init__() method and "self" in Python?

Hey people,

I started learning Kivy today. Kivy is a Python framework for cross-platform apps. However, I'm still a beginner in Python, and since Kivy requires a good grasp of OOP, I've just watched a few tutorials and understood the concept of classes, and have already practiced a bit. I also understand that "self" is a reference to the current instance. But why can you only access instance variables from a method if they are preceded by "self"?

And my second question is why there's sometimes a **kwargs in the initialization of the __init__() method. So here's some sample code:

 class MyGrid(GridLayout): def __init__(self, **kwargs): super().__init__(**kwargs) self.word_list = ["python", "java", "ruby", "javascript"] self.guess_word = [] self.secret_word = "" self.remaining_guesses = 6 self.img_path = "img/hangman_{}.png" self.create_game_layout() self.new_game()

This is just the __init__() method of a MyGrid class that inherits from GridLayout.

Oh yeah. I didn't quite understand what this "super()" meant either.

I would be very grateful if someone could help me. I really want to program an Android Kivy app for Hangman for a project in computer science class. But first, I need to understand these topics.

LG Code Snake

(2 votes)
Loading...

Similar Posts

Subscribe
Notify of
4 Answers
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
KarlRanseierIII
1 year ago

super() is the parent class that was inherited, so GridLayout.

kwargs are keyword(ed) args, so named arguments, so if you pass anything like n=5 when calling. It is therefore not transferred to position (positional) but to name (name/keyword).

Your constructor (Ctor) therefore takes the keyword args and passes it to the parent class (**kwargs here denotes the totality of all arguments passed by name):

super().__init__(**kwargs)

Call constructor of parent class with keyworded arguments.

P.S.: the first parameter of a method is a reference to the object instance, i.e. the current object.

P.P.S.: Technically, it’s a bit more complex because the * actually make a packing/unpacking, but that’s what you might want to keep in mind.

regex9
1 year ago

But why can one access the instance variables from a method only if it is “self”?

The parameter self refers to the object and only that knows its attributes bound to it.

Suppose you have this application:

class Person:
  def __init__(self, name):
    self.name = name

  def say_name(self):
    print(self.name)

person = Person("Max")
person.say_name()

A type object Person is created and an attribute Name bound. The call of say_name is implicitly nothing but a normal function call, in which the object is transferred:

say_name(person)

This object is sent to the parameter self given. If there were no parameters, there would be no reference to the object context.

And my second question is what is sometimes such a **kwargs when initializing the __init__() method.

This allows the transfer of any number of named parameters.

This special parameter feature can basically be used for any normal function:

def print_data(**arguments):
  for key, value in arguments.items():
    print(key, value)

print_data(age=82, name="Pete", location="New York")

In your case, it is used to be able to record arguments as flexible as the basic type (GridLayout).

Oh, yeah. What this “super()” means I didn’t quite understand.

This is based on the basic type GridLayout accessed.

Suppose you want to create a Grid layout with three columns and three rows. You can do this:

layout = GridLayout(cols=3, rows=3)

the GridLayout-type has a constructor that allows the transfer of named parameters.

Now you’ve created your own type, GridLayout inherit. This can be done in this implementation:

class MyGrid(GridLayout):
  def __init__(self):
    # do something ...

not to offer what you are up to GridLayout-Type could use: You cannot specify the number of columns and rows directly when creating. For this, the parameters must first be passed.

Restratively, you could first proceed like this:

class MyGrid(GridLayout):
  def __init__(self, cols, rows):
    super().__init__(cols=cols, rows=rows)

layout = MyGrid(3, 3)

The Super-Function accesses the base type and calls its constructor to pass the two values.

However, as far as your type would allow only a setup with columns and rows. Other values that could be defined when creating a grid layout (e.g. distances between the individual cells) are not yet supported. By offering the same designer as the basic type and passing the parameter directly, the same flexibility as the basic type is obtained.

class MyGrid(GridLayout):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)

layout = MyGrid(cols=3, rows=3, spacing=5)
W00dp3ckr
1 year ago

So, with most OO speeches, “self” is implicit. I mean, you’re doing operations on an object instance of a class. At Python you have to say that the ones on the object operate “self” so “this object”. Class methods are then the methods that do not take “self” as parameters. kwargs are arguments specified as keyword=value pairs.