0

Sorry if it's a stupid question but I'm a beginner and couldn't find the answer on google, so I thought on asking here to learn. When I write

Class Buttons:
 def play_b(self):
    self.play_button = Button(main_window, text="Play")
    self.play_button.grid(row=0, column=0)

It returns TypeError: play_b() missing 1 required positional argument: 'self'

However, when I write the following it works perfectly:

class Buttons:
 def play_b():
    play_button = Button(main_window, text="Play")
    play_button.grid(row=0, column=0)
   

My question is: Why this happen? shouldn't functions always have the self keyword?

Edit: This is all the code so far: this is all the code so far:

from tkinter import *

main_window = Tk()
main_window.geometry("720x480")

class Buttons:
    def play_b():
        play_button = Button(main_window, text="Play")
        play_button.grid(row=0, column=0)

Buttons.play_b()
  • 3
    Could you please ensure that you're providing a [mre] -- the shortest possible code that someone else can copy-and-paste with no changes whatsoever to see the exact same error? The code right now never tries to _invoke_ `play_b`, so no errors that happen at invocation time ever get a chance to take place. – Charles Duffy Jul 05 '20 at 02:45
  • 1
    It's not clear what `play_button()` is. Where is that defined? And the error is from `play_b()` but you don't show where you're calling that. – Mark Jul 05 '20 at 02:45
  • 2
    You are apparently trying to call the method on *the class itself* (something like `Buttons.play_b()`), rather than an *instance of the class* (which would be `Buttons().play_b()`). The latter is how classes are normally used. – jasonharper Jul 05 '20 at 02:45
  • ...that is to say, the normal usage is something like `buttons = Buttons(); buttons.play_b()`. – Charles Duffy Jul 05 '20 at 02:46
  • I've edited the post and wrote all the code I've wrote – Miguel Arrieche Jul 05 '20 at 02:51
  • Yeah, it works using self with Buttons().play_b(). That's what was left. Though part of my question is still unanswered; Why this happens?. Also thanks for showing me my error. – Miguel Arrieche Jul 05 '20 at 02:56
  • A function only becomes a method when called with an instance object. `type(Buttons.play_b)` is ``. `type(Buttons().play_b)` is ``. You can take a regular function and add it to a class and bingo! you've got a method. Its first parameter had better be the `self` object. – tdelaney Jul 05 '20 at 03:04
  • Your first block of code is invalid python. You can't get the error you say you do with that code. – Bryan Oakley Jul 05 '20 at 03:04
  • Does this answer your question? [What is the purpose of the word 'self'?](https://stackoverflow.com/questions/2709821/what-is-the-purpose-of-the-word-self) .. more [Python 'self' keyword](https://stackoverflow.com/questions/6019627/python-self-keyword), [When do you use 'self' in Python?](https://stackoverflow.com/questions/7721920/when-do-you-use-self-in-python) – wwii Jul 05 '20 at 03:28

1 Answers1

1

I believe you've messed up the method call as mentioned in the comments. Call the method like so

obj = Buttons() # assuming no parameterized __init__ (constructor) method
obj.play_b()

In the second case, it's a static method i.e. it doesn't do anything with the object's (self) data, and so it works. But the changes won't be reflected in the object. See more on static methods here.

EDIT

After you updated the question, I see that you've called the class method directly, without instantiating it. Hence the problem. The solution is still the same as what I've mentioned before. Create an object (instantiate) first, then call the method using that object.

Eeshaan
  • 1,557
  • 1
  • 10
  • 22
  • A method needs the `@staticmethod` decorator to be static. It doesn't matter if the method doesn't happen to use `self`, it would still have to be there in the call. There is no good explanation as to why 1 failed and 2 worked because it failed in the call to the method, not the method itself. I think there was something in the code not shown in the examples posted. – tdelaney Jul 05 '20 at 02:58
  • That would of course be more readable, but as shown in the website I've linked, it's not a must. – Eeshaan Jul 05 '20 at 03:01
  • That link showed `staticmethod` used as a function and a decorator. A decorator is just syntactic sugar for using the function. OP doesn't have a static method. Like all regular methods, it is a function bound to the class (no self) but python converts it to a method when called from a class instance. – tdelaney Jul 05 '20 at 03:11