PyCharm-从海龟进口*-提供未使用的进口参考

时间:2019-04-29 12:32:59

标签: python pycharm python-import turtle-graphics

PyCharm无法正确导入/解析。该代码可以正常运行,但是并没有完成代码,并且将其标记为错误(红色波浪线)。

证明这一点的代码如下:

from turtle import *

forward(40)
right(45)
forward(80)


import turtle

t = turtle.Turtle()

t.forward(40)
t.right(45)
t.forward(80)

还有一张图片展示了PyCharm中的问题:

https://prnt.sc/ni9dvk

有人对如何解决此问题有任何想法吗?无法使用from X import Y很烦人。

3 个答案:

答案 0 :(得分:2)

根据经验,无论包X是什么或它的文档说什么,都不要使用from X import *,这只会导致以后的bug。

为什么应避免“明星进口”

from turtle import *

def forward():
    print('forward')

forward(45)

您认为会发生什么?

turtle.forward被本地定义的forward函数覆盖,我们将收到错误TypeError: forward() takes 0 positional arguments but 1 was given

在这种情况下为什么有效

from turtle import *

forward(40)

要了解即使Pycharm指出forward未定义,上述方法为何仍有效,我们必须了解turtle模块的实现方式,然后了解Python导入的工作方式以及Pycharm如何检查“名称的定义。

turtle.py

tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
               'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
        'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
        'getshapes', 'listen', 'mainloop', 'mode', 'numinput',
        'onkey', 'onkeypress', 'onkeyrelease', 'onscreenclick', 'ontimer',
        'register_shape', 'resetscreen', 'screensize', 'setup',
        'setworldcoordinates', 'textinput', 'title', 'tracer', 'turtles', 'update',
        'window_height', 'window_width']
_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
        'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
        'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
        'fillcolor', 'filling', 'forward', 'get_poly', 'getpen', 'getscreen', 'get_shapepoly',
        'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
        'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
        'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
        'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
        'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',
        'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'shapetransform', 'shearfactor', 'showturtle',
        'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards',
        'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
        'write', 'xcor', 'ycor']
_tg_utilities = ['write_docstringdict', 'done']

__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
           _tg_utilities + ['Terminator'])  

...

如您所见,它只是准备一些字符串列表(它们是函数/类/等的名称),然后将所有内容合并为一个列表,并将所有内容分配给__all__全局变量。

我不会详细介绍__all__(因为有关该主题的SO上有很多问答,例如Can someone explain __all__ in Python?),但是基本上它告诉解释器在执行操作时应该使用哪些名称from X import *

当您进行from turtle import *然后使用forwardright等时,由于它们的名称位于__all__中,因此可以使用它们,但是Pycharm不知道它们将由__all__运行时公开。

答案 1 :(得分:0)

这里发生的是Python turtle是不寻常的,因为它有两个不同的接口,一个是 functional 功能,一个是 object-oriented 功能。如果您使用面向对象的对象,那么一切都应该正常工作:

from turtle import Screen, Turtle

yertle = Turtle()

yertle.forward(40)
yertle.right(45)
yertle.forward(80)

screen = Screen()

screen.exitonclick()

具有功能性界面,使初学者更轻松:

from turtle import *

forward(40)
right(45)
forward(80)

exitonclick()

或:

import turtle

turtle.forward(40)
turtle.right(45)
turtle.forward(80)

turtle.exitonclick()

但是您不应该将两者混为一谈!因为这是造成乌龟混乱的主要原因。

PyCharm的问题在于,乌龟 functional API是在加载时从面向对象 API派生的,因此PyCharm在扫描时不存在源文件。乌龟方法都映射到 default 乌龟上,而屏幕方法都映射到单个屏幕实例上。

答案 2 :(得分:-1)

尝试一下:

from turtle import Turtle

它必须工作。

问候。