简体   繁体   English

在 Python 3 中使用海龟时出现令人困惑的错误消息

[英]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.我正在为学校做 CSP 作业,在测试代码的颜色部分是否正常工作时,我收到了一条相当令人困惑的错误消息。 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.这对我来说没有任何意义,因为我对 python 有点陌生。 Help?帮助?

In the first line, you import the turtle module.在第一行中,您导入了turtle模块。

In the second line, assign the Turtle class from the turtle module to the name turtle .在第二行中,将来自turtle模块的Turtle class 分配给名称turtle This overwrites the value of the name turtle , so it no longer refers to the module -- it now refers to your Turtle class.这将覆盖名称turtle的值,因此它不再指代模块——它现在指代您的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. 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.请注意,class 的 object 与 class 本身不同。 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.调用Turtle.color("brown")"brown"作为self参数传递,但 function 期望self参数是Turtle class的 object 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.请记住通过调用turtle.Turtle turtle.Turtle()创建Turtle class 的实例,而不仅仅是复制它的值。

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

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, ie, a type of data , just like int or str . turtle.Turtle是一个 class,即数据类型,就像intstr一样。

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.通过编写turtle = turtle.Turtle ,我们只需给 class 另一个名称(并且停止为模块使用该名称,这可能会导致其他问题),而不是创建实例。 So the code turtle.color("brown") is trying to call the color method on the class, instead of the instance.所以代码turtle.color("brown")试图调用 class 上的color方法,而不是实例。

Instead, we want to create an instance , by calling the class: turtle.Turtle() .相反,我们想通过调用 class:turtle.Turtle 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?好的,但是 go 从那里到底是怎么出错的?


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. 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.这就是方法调用正常工作的方式: object 实际上不包含该方法,但它的 class 包含。 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.当在对象的 class 而不是 object 本身中找到某些内容时,将执行更多步骤以使该方法像实际方法一样工作,而不是普通的 function。

But also in Python, the classes themselves are objects.而且在 Python 中,类本身就是对象。 (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. (这就是他们可以包含这些方法的原因。)所以他们有自己的 class (通常是名为type的那个),以及他们自己的属性查找过程。 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).代码turtle.color("brown")首先尝试在 class 中查找color (因为这是turtle当前的名称),然后找到它(因为它直接在 class 中查找,这就是它的实际位置)。 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.这意味着color被称为普通的 function,而不是方法。 Which means that the string "brown" is received as self .这意味着字符串"brown"作为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.这意味着该方法中的代码将尝试像使用Turtle一样使用字符串,但事实并非如此。 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). "brown"是一个'str' object ,它has no attribute '_color' (字符串本身和str class 都不包含它)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM