为了满足 Linter 的要求而修改代码是不好的做法吗

问题描述 投票:0回答:1

我使用 neovim 并通过 mason-lspconfig 使用 pyright linter 来静态类型检查我的代码。我写了很多类型提示;这是一个例子:

def example(user_input: str) -> None:
    tokens: List[Token] = []
    position = 0
    length_of_input: int = len(user_input)
    
    while position < length_of_input:
        match: Union[re.Match[str], None] = None

        sliced_input = user_input[position:]

        # There's more code but you probably get the point        

我有一系列关于类型提示最佳实践的问题:

  1. 如果函数返回 None,您是否仍应像我对示例函数所做的那样指定它?
  2. 我看到许多其他Python程序员使用AnyStr而不是str。我不是在问为什么,我只是想知道这是否重要,以及使用 str 而不是 AnyStr 是一个不好的做法吗?

这就是我要讲的关于满足 linter 的部分。这是我的代码最初的样子:

# There's a lot of context that goes with this but just assume factor_node_result.tokens is a List
tokens = factor_node_result.tokens.copy()

linter 告诉我

None has no method copy()

我把它改成了这样,这样它就不再抱怨了;但是,我的代码的两个版本都可以工作。当我使用这个版本时,linter 就不再抱怨了:

if factor_node_result.tokens is not None:
    tokens = factor_node_result.tokens.copy()
  1. 无论如何,我可以使用类型提示魔法或配置我的 linter 以某种方式忽略这种检查
  2. 为了满足 linter 而更改代码是一种不好的做法吗?
python type-hinting static-analysis
1个回答
0
投票

事实是,如果你有一个好的 linter 并且编写了不错的代码,那么 linter 抱怨的任何问题都是你的代码的潜在问题。

“但它可以在没有类型的情况下工作”并不能改变这一点。其一,Python 总是在没有类型提示的情况下工作,这不是它存在的原因。其次,除非您绝对确定它可以实现任何可能的值,否则您不能真正说它有效。即便如此,它现在有效的事实并不意味着它将来仍然有效,当您从其他地方调用函数时,或者可能在新版本的 Python 上运行脚本时,具有不同的依赖项等。

至于检查

None
,是的,在某些情况下,如果函数可以合理地返回
None
(或者退出而不显式返回任何内容,这是相同的)。例如:

from typing import Optional


def question(answer: bool) -> Optional[int]:
    if answer:
        return 42


wisdom = question(False)

if wisdom is None:
    print("You're not worthy!")
else:
    print(f"Your answer is {wisdom}")

但是,始终返回

None
的函数(即仅依赖于副作用,或者只是对对象进行操作的方法)不应需要提示。毕竟,您不会在
None
上调用方法。

所以,对你的问题#1 说“不,除非”,对问题#2 说“不,因为”——这不仅仅是为了满足 linter,而是因为 linter 可能有一个观点。

© www.soinside.com 2019 - 2024. All rights reserved.