2

I'm a little messy with classes in python, I get a class code from the web, but when I did a change in the code, I got the error

SyntaxError: non-default argument follows default argument.

Following the code below:

class button():
    def __init__(self, color, x, y, width, height, text='',color_font): #the problem is color_font argument
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text
        self.color_font = color_font

Why did I get this error? I referenced the color_font in the __init__ function, therefore it should work second this link: https://www.w3schools.com/python/python_classes.asp

5
  • Because color_font is a non-default argument, and it follows text which is a default argument (=''). Commented May 4, 2020 at 14:01
  • 2
    This has NOTHING to do with classes, the same problem would occur with any sort of function definition. Commented May 4, 2020 at 14:03
  • @jasonharper what's a non-default parameter? Commented May 4, 2020 at 14:04
  • I suggest to keep font_color rightmost, see my answer. Commented May 4, 2020 at 14:35
  • @LucasVital The error does not say non-default parameter but non-default argument -- arguments are the values you pass to a function when you call it, if you don't pass an argument, python tries to find a default argument for the given parameter. Commented May 4, 2020 at 14:41

3 Answers 3

3

You need to put your parameter text='' after all parameters that aren't optional (i.e., arguments that don't have default values). From the documentation:

If a parameter has a default value, all following parameters up until the “*” must also have a default value — this is a syntactic restriction that is not expressed by the grammar.

class button():
    def __init__(self, color, x, y, width, height, color_font, text=''):
        ...
Sign up to request clarification or add additional context in comments.

3 Comments

This way it seems not very useful. It looks like color_font is the color for the text of the button. How would you get benefit from an empty default text in combination with different font colors?
@Wolf This seems a bit out of the context of the question, considering we can't even see all of the code. Perhaps there is code that sets button text to a specific string if the empty string is passed in. Perhaps the color of the font dictates other behavior such as the color of the border of the button. If color_font in fact has no effect if text == '', then yes, maybe it too should be an optional parameter.
To me the relation between color_font and text is quite obvious in the case of a button class, also it seems you treat the terms parameter and argument as synonyms, they aren't. I'm sure that the error message in question was carefully worded.
1

A default argument is the value ('' in your case) that is assigned to a formal parameter (text in your case) in a function (__init__ in your case); non-default argument means that such a default argument is missing for a formal parameter (color_font in your case).

Python supports default arguments only at the end of the parameter list, so that you can call a function with a minimum of arguments.

Normally, when designing a function (the same is true for __init__), you chose such an order of parameters with default arguments that the most specialized options go rightmost. That's why I'd suggest to add a default argument to font_color as well and keep it the last parameter. It's much more likely that you have lots of buttons with different text and not as many different font colors but with the default text which is empty.

In other words, change your code into the following

class button():
    def __init__(self, color, x, y, width, height, text='', color_font='black'):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text
        self.color_font = color_font

useful default arguments

Default arguments are there to make calling a function easier. to me this looks somewhat okay

button('gray', 4, 4, 64, 16, 'one', 'red')
button('gray', 4, 24, 64, 16, 'two')
button('gray', 4, 44, 64, 16, 'three')

but this looks somewhat odd

button('gray', 4, 4, 64, 16, 'red', 'hello')
button('gray', 4, 24, 64, 16, 'blue')
button('gray', 4, 44, 64, 16, 'green')

when the text (in different font colors) is empty. Of course, there is much more space for optimization in your class, think of the repetition potential for color or height.

one more advice

Try to read as much from an error message as you can, and read careful

SyntaxError: non-default argument follows default argument.

The error does not tell you about a non-default parameter but about a non-default argument. Arguments are the values you pass to a function when you call it, if you don't pass an argument in a place belonging to a parameter, python uses a default argument for it, if it cannot find such, it raises an error. This is the reason why parameters with default arguments do not make sense before parameters without: mandatory arguments (the ones without default argument) match their parameter by position, and as to reach this position, you have to place the correct amount of arguments before it, default arguments would never get used this way.

Comments

0

The problem is with the fact that there's a default argument passed down to text in the constructor. Python does not allow you to have function arguments with no default values following arguments that do have default values.

Swap their places:

class button():
    def __init__(self, color, x, y, width, height, color_font, text=''): 
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text
        self.color_font = color_font

Comments