防止字符串列表中字符串串联的书写风格

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

假设我有一个字符串列表/元组,

COLOURS = [
    "White",
    "Black",
    "Red"
    "Green",
    "Blue"
]

for c in COLOURS:
    # rest of the code

有时我忘记在列表中的每个条目后面放置逗号(上面片段中的

"Red"
)。这会产生一个
"RedGreen"
,而不是两个单独的
"Red"
"Green"
列表项。

由于这是有效的 Python,因此 IDE/文本编辑器不会显示警告/错误。错误的值仅在测试过程中才会引起注意。

我应该使用什么写作风格或代码结构来防止这种情况发生?

python code-structure
4个回答
5
投票

您错误地认为“没有 IDE/文本编辑器显示警告/错误”。 Pylint 可以使用规则 implicit-str-concat (W1404) 和标志 check-str-concat-over-line-jumps 来识别此问题。 (就此而言,有很多有效的 Python 内容,linter 会警告您,例如 bare

except:
。)

就个人而言,我使用的是 VSCode,因此我通过 Python 扩展启用了 Pylint (

python.linting.pylintEnabled
) 并设置了 pylintrc,如下所示:

[tool.pylint]
check-str-concat-over-line-jumps = yes

现在 VSCode 会针对您的列表发出此警告:

列表中发现隐式字符串连接  pylint(implicit-str-concat)  [Ln 4, Col 1]


最后,可能还有其他 linter 可以找到相同的问题,但 Pylint 是我发现的第一个。


1
投票

使用@wjandrea 发现的内容,这是一个可能的解决方案。它并不漂亮,但它可以正确检测到此代码具有隐式字符串连接。我让它只是打印出警告而不是崩溃,但如果你愿意,可以修改它以引发错误。

您也可以在您的文件上运行

pylint
,但我假设您正在寻找一种“编程”方式来检测何时发生这种情况,并且只有这种情况发生。

import pylint.lint
import sys

def check_for_implicit_str_concat():
    pylint.lint.reporters.json_reporter.JSONReporter.display_messages = lambda self, layout: None

    options = [
        sys.argv[0], 
        '--output-format=pylint.reporters.json_reporter.JSONReporter',
        '--check-str-concat-over-line-jumps=y'
    ]
    results = pylint.lint.Run(options, do_exit=False)
    for message in results.linter.reporter.messages:
        if message['message-id'] == 'W1403':
            print(message)

if __name__ == "__main__":
    check_for_implicit_str_concat()
    COLOURS = [
        "White",
        "Black",
        "Red"
        "Green",
        "Blue"
    ]

输出:

{
  "type": "warning",
  "module": "test",
  "obj": "",
  "line": 22,
  "column": 0,
  "path": "test.py",
  "symbol": "implicit-str-concat-in-sequence",
  "message": "Implicit string concatenation found in list",
  "message-id": "W1403"
}

1
投票

我会采用这样的方法,这甚至可以提高颜色的可维护性和可扩展性:

  • 使用枚举(或字典)来表示颜色,这样您就可以按以下方式使用它们:

    Colours.RED
    Colours.BLUE
    。可能是最好的解决方案,但这实际上取决于您的应用程序的上下文。

  • 创建一个非常简单的

    Colour
    类,其中包含颜色的字符串字段和初始化它的构造函数。这样,下面的代码看起来就像这样:

    COLOURS = [Colour("white"), Colour("green")]
    

    它的缺点可能是在一定程度上过度构建您的代码,并且现在必须处理稍微不同的颜色对象(可能使用

    c.get_colour()
    c.color
    。也许这根本不是缺点,具体取决于您的规模申请。

  • 另一个“解决方案”是采用函数式风格,创建一个非常冗余的函数,将颜色作为字符串并将其返回。我不喜欢这个解决方案,因为它可能不会给您带来任何好处。

大多数情况下,在生产代码中,如果列表中有一堆这样的常量(除非您专门为某种枚举定义它们),而不是枚举它们或类似的东西 - 您最可能做错了什么,所以解决方案是避免这种情况。


1
投票

同时使用Black格式化程序和Pylint,就可以开始了。

如果您的列表如下:(不以逗号结尾)

COLOURS = [
    "White",
    "Black",
    "Red"
    "Green",
    "Blue"
]

然后格式化后就变成:

COLOURS = ["White", "Black", "Red" "Green", "Blue"]

它们现在在同一行...所以 Pylint 抱怨它:“在列表中发现隐式字符串连接”。

如果您有相同的列表但以逗号结尾:

COLOURS = [
    "White",
    "Black",
    "Red"
    "Green",
    "Blue",
]

它会变成:

COLOURS = [
    "White",
    "Black",
    "Red" "Green",
    "Blue",
]

正如您所看到的,无论哪种情况,黑棋都会迫使它们排成一行。所以你会收到 Pylint 的警告。

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