0

It is apparently impossible to pass attributes of an object to its own methods:

def drawBox(color):
    print("A new box of color ", color)
    return

class Box:
    def __init__(self, color):
        self.defaultColor = color
        self.color = color

    def update(self, color = self.defaultColor):
        self.color = color
        drawBox(color)

This does not work:

Traceback (most recent call last):
  File "<string>", line 5, in <module> 
File "<string>", line 9, in Box 
NameError: name 'self' is not defined

I found a way to bypass this issue like this:

def drawBox(color):
    print("A new box of color ", color)
    return

class Box:
    def __init__(self, color):
        self.defaultColor = color
        self.color = color
    def update(self, color = None):
        if color == None:
            self.color = self.defaultColor
        else:
            self.color = color
        drawBox(color)

Is there a better (more elegant?) way to do this?

3
  • "It is apparently impossible to pass attributes of an object to its own methods:" that just doesn't make sense. You don't pass attributes. You pass objects. It is perfectly possible to pass an object using an attribute reference. The problem is that self is not defined in the class body -- of course not, self is simply the conventional name given to the first paramter of a method, it won't be defined until you call the method Commented Jun 7, 2022 at 22:54
  • in any case, your solution is fine. Maybe use if color is None: ... to be more idiomatic Commented Jun 7, 2022 at 22:55
  • Note, def update(self, color = self.defaultColor): is not passing anything, that is part of a function definition. There is no "passing" involved because it isn't a function call Commented Jun 7, 2022 at 22:57

1 Answer 1

3

The reason you can't use self.color as a default parameter value is that the default is evaluated at the time the method is defined (not at the time that it's called), and at the time the method is defined, there is no self object yet.

Assuming that a valid color is always a truthy value, I would write this as:

class Box:
    def __init__(self, color):
        self.default_color = self.color = color

    def draw(self):
        print(f"A new box of color {self.color}")

    def update(self, color=None):
        self.color = color or self.default_color
        self.draw()
Sign up to request clarification or add additional context in comments.

2 Comments

I mean, this really isn't more "elegant" that the pretty canonical solution the OP already found
In the eye of the beholder, I guess, but I really love Python's or operator for being able to turn a very common if/else pattern into a graceful one-liner.

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.