TKTrch3
TKTrch3

Reputation: 29

Confusing error message while using turtle in Python 3

I'm doing a CSP assignment for school and I was getting a rather confusing error message while I was testing whether the color portion of my code functioned. This is my code:

import turtle
turtle = turtle.Turtle
turtle.color("brown")

And this is the error message

 Traceback (most recent call last):
  File "/tmp/sessions/1ab7a960b2c10b4b/main.py", line 3, in <module>
    turtle.pencolor("brown")
  File "/usr/lib/python3.6/turtle.py", line 2257, in pencolor
    return self._color(self._pencolor)
AttributeError: 'str' object has no attribute '_color'

It does not make any bit of sense to me, as I am somewhat new to python. Help?

Upvotes: 0

Views: 473

Answers (2)

pho
pho

Reputation: 25489

In the first line, you import the turtle module.

In the second line, assign the Turtle class from the turtle module to the name turtle. This overwrites the value of the name turtle, so it no longer refers to the module -- it now refers to your Turtle class.

When you try to do turtle.color, you try to access the color function of turtle, which in this case is your Turtle class, instead of acting the color function of the turtle module, or the color method of an object of the Turtle class. Note that an object of a class is not the same as the class itself. Calling Turtle.color("brown") passes "brown" as the self argument, but the function expects the self argument to be an object of the Turtle class. This is why you see that error.

To fix this, assign a different name to your turtle so that you don't shadow the module. And remember to create an instance of the Turtle class by calling turtle.Turtle(), rather than just copying its value.

import turtle
my_turtle = turtle.Turtle() # Create an instance, and assign it to a DIFFERENT name
my_turtle.color("brown")    # Call method of that instance

Upvotes: 2

Karl Knechtel
Karl Knechtel

Reputation: 61525

The cause here is a common typographical error, but the error message is interesting enough to be worth an answer. (There might be a duplicate, but I'm not sure how to find it right now.)

turtle.Turtle is a class, i.e., a type of data, just like int or str.

By writing turtle = turtle.Turtle, we simply give the class another name (and also stop using that name for the module, which can cause other problems), rather than creating an instance. So the code turtle.color("brown") is trying to call the color method on the class, instead of the instance.

Instead, we want to create an instance, by calling the class: turtle.Turtle(). Then we should use a name for that which doesn't cause conflicts. Thus:

import turtle
my_turtle = turtle.Turtle()
my_turtle.color("brown")

Okay, but exactly how did it go wrong from there?


In Python, when the code looks for an attribute on some object (anything that follows the .), it looks in the object itself first, and then in the class. That's how method calls work normally: the object doesn't actually contain the method, but its class does. When something is found in the object's class instead of the object itself, then more steps are followed to make the method work like an actual method, rather than an ordinary function.

But also in Python, the classes themselves are objects. (That's why they can contain the methods.) So they have their own class (normally, the one named type), and their own attribute lookup process. The code turtle.color("brown") first tries to find color in the class (because that's what turtle currently names), and finds it (because it's looking directly in the class, and that's where it actually is). Since it was found directly, the method magic doesn't happen.

That means that color was called like an ordinary function, not like a method. Which means that the string "brown" is received as self.

Which means that the code in that method will try to use a string as if it were a Turtle, which it isn't. Which causes the error we see. "brown" is a 'str' object, and it has no attribute '_color' (neither the string itself, nor the str class, contains it).

Upvotes: 1

Related Questions