【发布时间】: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() 的参数的预期相矛盾。
我意识到答案可能是:“如果您的代码有效,那么问题是什么?”但问题的一部分是我想信任我用于开发的工具。如果我开始关闭警告或只是假设一切都很好,与工具相反,我还不如不使用该工具。
【问题讨论】: