[原创] 小心PyCharm的import带来的unresolved reference误导

有时候你可能会遇到这样的故事:git clone一个Python的GitHub项目下来,配置好了对应的Anaconda环境,安装好了依赖的package,用PyCharm打开了项目,打开一个.py代码文件,发现PyCharm在文件开头几行就给标注了波浪线,提示unresolved reference XXX。而且,尽管PyCharm提示有错,你却可以运行代码。
“我完全就是按项目要求的版本装的各种依赖包,怎么会找不到这个定义?”你心里可能会很不爽。
这个时候,你要看清楚了,有可能是PyCharm给了你误导,其实你什么都做对了,只是PyCharm显示错了而已。

下面就举一个实际的例子。
假设你安装了PyTorch 1.2.0。在一个自己写的代码文件中,有下面两句import:

from torch.nn.parallel import DistributedDataParallel as DDP
from torch.nn.parallel import DistributedDataParallelCPU as DDPC

文章来源:https://www.codelast.com/
你会发现,第1行没问题,第2行被PyCharm标注了波浪线,提示 unresolved reference XXX,意思就是 DistributedDataParallelCPU 找不到。
所以PyTorch 1.2.0里面真的没有 DistributedDataParallelCPU 吗?你可以去网上搜,也可以简单地用下面的方法检查一下:
既然 DistributedDataParallel 这里不提示错误,而且从名字上看,DistributedDataParallel 和 DistributedDataParallelCPU 是有关联的,因此,在PyCharm里先按住Ctrl键(Linux下),再用鼠标点击 DistributedDataParallel,即可打开它的代码 distributed.py,然后用快捷键Alt+F5(Linux下)调出“Select In”菜单:

选择菜单里的“Project View”,回车,PyCharm会定位到该文件所在的目录:

双击 parallel 这个package下的 __init__.py 文件,看看里面写了什么:

from .parallel_apply import parallel_apply
from .replicate import replicate
from .data_parallel import DataParallel, data_parallel
from .scatter_gather import scatter, gather
from .distributed import DistributedDataParallel

__all__ = ['replicate', 'scatter', 'parallel_apply', 'gather', 'data_parallel',
           'DataParallel', 'DistributedDataParallel']

def DistributedDataParallelCPU(*args, **kwargs):
    import warnings
    warnings.warn("torch.nn.parallel.DistributedDataParallelCPU is deprecated, "
                  "please use torch.nn.parallel.DistributedDataParallel instead.")
    return DistributedDataParallel(*args, **kwargs)

文章来源:https://www.codelast.com/
在这个文件中,你会看到一个名为 __all__ 的list,以及在外面 import 的时候提示 unresolved reference 的 DistributedDataParallelCPU,果然它是真的存在的,只不过已经被警告deprecated了,而且它直接返回的就是 DistributedDataParallel。

那么 __all__ 这个list又是什么,为什么在外面 import DistributedDataParallel 可以,import DistributedDataParallelCPU 却提示 unresolved reference?
__all__ 是由字符串元素组成的,它定义了当你使用 from <module> import * 导入某个模块的时候能导出的符号(variable,method,class等),__all__ 只会影响 from <module> import * 这种导入方式,对于 from <module> import <member> 导入方式并没有影响,仍然可以从外部导入。
所以其实外部代码里的 from torch.nn.parallel import DistributedDataParallelCPU as DDPC 没有错,不要被PyCharm误导了。我测试了一下,同样的代码,在VSCode里,启用“Python extension for Visual Studio Code”插件后,它能识别出来PyCharm认为有错的那个import,点击它能跳到正确的source里。

文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤ 
转载需注明出处:codelast.com 
感谢关注我的微信公众号(微信扫一扫):

wechat qrcode of codelast

发表评论