3

I'm attempting to write a class method that takes 3 keyword arguments. I've used keyword arguments before but can't seem to get it to work inside of my class. The following code:

def gamesplayed(self, team = None, startyear = self._firstseason,
                endyear = self._lastseason):

    totalGames = 0

    for i in self._seasons:
        if((i.getTeam() == team or team == "null") and
           i.getYear() >= startyear and i.getYear() <= endyear):

            totalGames += i .getGames()

    return totalGames

produces the error:

NameError: name 'self' is not defined

If I take out the keyword arguments and make them simple positional ones, it works fine. Therefore I am not sure where my problems lies. Thanks in advance for any help.

2 Answers 2

8
def gamesplayed(self, team = None, startyear = self._firstseason, endyear = self._lastseason):

In the function declaration you are trying to reference instance variables using self. This however does not work as self is just a variable name for the first argument of the function which gets a reference to the current instance passed in. As such, self is especially not a keyword that always points to the current instance (unlike this in other languages). This also means that the variable is not yet defined during the declaration of the function.

What you should do is to simply preset those parameters with None, and preset them to those values in that case inside the function body. This also allows users to actually parse a value to the method that results in the default values without having to actually access the values from somewhere inside your class.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the in depth explanation. It made everything a lot more clear.
As rightfold points out below, one needs to be careful that None is not already used as a valid value a user may pass, for example in this code if None was to mean to apply no limit.
2

Default values for keyword arguments are bound at module construction time, not at class instance construction time. This is why self is not defined in this context.

The same fact about default values can create all sorts of problems any time you want a keyword argument where the default value updates every time the function is called. When you run the program, you'll find that the default value you expect to be updating is always set to the value constructed when the module was first initialized.

I would advise using None as a default keyword parameter in both instances, as poke and others have suggested. Your code could look something like:

def gamesplayed(self, team=None, startyear=None, endyear=None):
    if not startyear:
        startyear = self._firstseason
    if not endyear:
        endyear = self._lastseason

1 Comment

Better use "if year is None" in case somebody calls the function with 0 and 9999 to cover all years.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.