【问题标题】:PyCharm Warnings and Expected Types: When To Care?PyCharm 警告和预期类型:何时需要关注?
【发布时间】:2018-03-08 02:26:10
【问题描述】:

关于 PyCharm 和警告的帖子和问题太多了,但对于 PyCharm 何时真正告诉你有用的东西,何时不是,似乎几乎没有达成共识,特别是关于“预期类型”的警告。我发现,发布到 IntelliJ / PyCharm 支持板通常并不能提供太多的路线图。

所以我保留了这个问题的标题有点笼统,但我将提供一个非常具体的示例,其中包含两个不同的警告,其中修复一个会导致执行错误。我希望这类警告可能有一个普遍的答案。也许答案只是 PyCharm 不太擅长这种检测。

上下文

所以这里考虑下面的代码:

def load_agent(pacman, no_graphics):
  python_path_string = os.path.expandvars("$PYTHONPATH")

  if python_path_string.find(';') == -1:
    python_path_dirs = python_path_string.split(':')
  else:
    python_path_dirs = python_path_string.split(';')

  python_path_dirs.append('.')

  for module_dir in python_path_dirs:
    if not os.path.isdir(module_dir):
        continue

    module_names = [f for f in os.listdir(module_dir) if f.startswith('agents_')]

我的 for 块中有更多代码,但与这里的问题无关。我还要说我的代码确实有效。但我担心的是我是否应该忽略关于类型的警告。

问题

我将从最后一行开始。如果你试图对你在 Python REPL 中传递的 startswith() 做任何奇怪的事情,你会被告知:

startswith first arg must be str or a tuple of str, not bytes

有道理。那么为什么 PyCharm 对这一行('agents_' 参数,具体来说:

Expected type 'Union[bytes, Tuple[bytes, ...]], got 'str' instead

此外,上面的第 9 行 (python_path_dirs.append('.')) 也提供了 PyCharm 警告(特别是针对“.”):

Expected type 'bytes' (matched generic type '_T'), got 'str' instead

解决方案尝试

对于第 9 行的问题,我知道我可以在字符串前面加上一个b。然而,这样做会导致其他问题。具体来说,它会导致最后一行出现执行问题(我最初提到的那个)。

所以要明确一点:上面的代码可以正常工作。如果我假设 PyCharm 正确地警告我,我会修复第 9 行,使其看起来像这样:

python_path_dirs.append(b'.')

这是 IntelliJ / PyCharm 团队提供的建议,我在其他一些 StackOverflow 答案中也看到了这一点。

但是,这样做会导致我上面代码中的最后一行出现此错误:

TypeError: startswith first arg must be bytes or a tuple of bytes, not str

给我上色

所以我担心这两条线似乎“相连”,因为它们都会收到警告。尝试满足第一个警告会导致第二行出现执行错误。然而,这些警告显然是在谈论不同的类型。此外,最后一行的警告似乎与 Python 本身所说的作为 startswith() 的参数的预期相矛盾。

我意识到答案可能是:“如果您的代码有效,那么问题是什么?”但问题的一部分是我想信任我用于开发的工具。如果我开始关闭警告或只是假设一切都很好,与工具相反,我还不如不使用该工具。

【问题讨论】:

    标签: python pycharm


    【解决方案1】:

    我不为 Jet Brains 工作,但我使用 Resharper 和 PyCharm 已经很多年了。这是我对该主题的一般经验/想法(特别是对于 Pycharm)。

    直到最近,随着类型提示 3.5+ 的可用性,PyCharm 不得不做出一些非常聪明的推断来提供类型检查和自动完成等功能。考虑到它做得非常好——但通常它的最佳猜测根本不正确。最终,有时只有开发人员才能决定它是否只是猜错了。

    如果您像我一样,您将无法忍受看到那些告诉您代码异味的小卷线。幸运的是,PyCharm 使您能够关闭对行、函数甚至文件的警告(例如,# noinspection PyTypeChecker - 在您的情况下)。当我知道 PyCharm 给了我错误的警告时,我会依赖这些。有时我完全不同意 PyCharm 并调整整个项目的检查。

    现在,有了类型提示,这应该会变得更好(只要开发人员使用它)。 PyCharm 将拥有更可靠的信息来做出决策。好消息是您可以提供帮助。

    1. 确保为所有个人项目使用类型提示
    2. 鼓励与您合作的其他人也这样做
    3. 请积极鼓励软件包维护者也这样做
    4. 通过添加类型提示为项目做出贡献

    如果每个开发人员都执行上述操作,那么您的大部分错误警告都会消失。在那之前,所有人都没有神奇的答案。您只需根据具体情况处理警告。

    【讨论】:

    • 优秀的建议。非常感激。关于何时“知道 PyCharm 给了你错误的警告”,更广泛的问题可能是:我怎么知道?例如,是否有可能查看我上面的代码并说这些警告是“错误的”?我意识到“是”的答案可能很明显,因为代码确实可以正常工作。在这种情况下,就像你说的那样,这是一个个案。
    • 在你的具体情况下——我去看了官方文档,查看了官方的用法,发现它匹配,所以PyCharm可能是罪魁祸首。这就是我通常这样做的方式 - 回到文档或示例。
    • 谢谢。这也符合我的发现。我想对我来说有趣的是当我觉得像startswith() 之类的东西在它期望提供给它的东西上显然很清楚时,警告是多么具体,就像append() 一样。但是,话虽如此,我确实明白你所说的关于 IDE 必须对给定的动态语言(如 Python 或 Ruby)进行类型推断的挑战。
    猜你喜欢
    • 2021-06-11
    • 2020-05-22
    • 2019-05-27
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    • 2019-10-05
    相关资源
    最近更新 更多