假设我有一个字符串列表/元组,
COLOURS = [
"White",
"Black",
"Red"
"Green",
"Blue"
]
for c in COLOURS:
# rest of the code
有时我忘记在列表中的每个条目后面放置逗号(上面片段中的
"Red"
)。这会产生一个 "RedGreen"
,而不是两个单独的 "Red"
和 "Green"
列表项。
由于这是有效的 Python,因此 IDE/文本编辑器不会显示警告/错误。错误的值仅在测试过程中才会引起注意。
我应该使用什么写作风格或代码结构来防止这种情况发生?
您错误地认为“没有 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 是我发现的第一个。
使用@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"
}
我会采用这样的方法,这甚至可以提高颜色的可维护性和可扩展性:
使用枚举(或字典)来表示颜色,这样您就可以按以下方式使用它们:
Colours.RED
,Colours.BLUE
。可能是最好的解决方案,但这实际上取决于您的应用程序的上下文。
创建一个非常简单的
Colour
类,其中包含颜色的字符串字段和初始化它的构造函数。这样,下面的代码看起来就像这样:
COLOURS = [Colour("white"), Colour("green")]
它的缺点可能是在一定程度上过度构建您的代码,并且现在必须处理稍微不同的颜色对象(可能使用
c.get_colour()
或 c.color
。也许这根本不是缺点,具体取决于您的规模申请。
另一个“解决方案”是采用函数式风格,创建一个非常冗余的函数,将颜色作为字符串并将其返回。我不喜欢这个解决方案,因为它可能不会给您带来任何好处。
大多数情况下,在生产代码中,如果列表中有一堆这样的常量(除非您专门为某种枚举定义它们),而不是枚举它们或类似的东西 - 您最可能做错了什么,所以解决方案是避免这种情况。
如果您的列表如下:(不以逗号结尾)
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 的警告。