如何处理Python中的长代码和命令
我尝试过搜索,但找不到和我情况相似的例子。我正在写一个程序,到目前为止我一直遵循每行不超过79个字符的规则。不过在某些情况下,我不太确定该在哪里换行。
以下是我遇到的问题:
self.proc.stdin.write('(SayText "%s")\n' % text.replace('\\', '\\\\').replace('"', '\\"'))
在这种情况下,当我在 '(SayText "%s")\n' 之后换行时,第二行的长度变成了80个字符。那我是不是应该在括号里某个地方再换行,比如这样?
self.proc.stdin.write('(SayText "%s")\n'
% text.replace('\\',
'\\\\').replace('"', '\\"'))
还是说把整个第三行移到第一个括号的开头,这样做会更好:
self.proc.stdin.write('(SayText "%s")\n'
% text.replace('\\',
'\\\\').replace('"', '\\"'))
还有一个例子在这里:
filename = tkFileDialog.askopenfilename(filetypes = (("Word list", "*.tldr"), ("All files", "*.*")))
我应该这样做吗?
filename = tkFileDialog.askopenfilename(filetypes = (("Word list",
"*.tldr"),
("All files",
"*.*")))
还是这样?
filename = tkFileDialog.askopenfilename(filetypes = (("Word list",
"*.tldr"),("All files", "*.*")))
有什么好的换行规则可以遵循吗?
谢谢。
7 个回答
一般来说,我会在“主要”语法连接符的第一个地方换行,然后对于普通语句的续行使用一个缩进,如果换行后面跟着冒号,就用两个缩进。不过,如果语法连接符是“.”,我更喜欢使用临时变量,因为这样通常更清晰。
对于你的例子:
self.proc.stdin.write('(SayText "%s")\n' % text.replace('\\', '\\\\').replace('"', '\\"'))
我会这样写:
self.proc.stdin.write(
'(SayText "%s")\n' % text.replace('\\', '\\\\').replace('"', '\\"'))
对于
filename = tkFileDialog.askopenfilename(filetypes = (("Word list", "*.tldr"), ("All files", "*.*")))
我会这样写:
filename = tkFileDialog.askopenfilename(
filetypes = (("Word list", "*.tldr"), ("All files", "*.*")))
对于有很多参数的函数调用,我有时觉得把每个参数放在单独一行上更清晰,尽管其实可以放在同一行。例如:
filename = some_function_call_with_long_args( the_first_argument = some_rather_long_expression, another_argument = some_other_expression )
会变成:
filename = some_function_call_with_long_args(
the_first_argument = some_rather_long_expression,
another_argument = some_other_expression )
甚至可以是:
filename = some_function_call_with_long_args(
the_first_argument = some_rather_long_expression,
another_argument = some_other_expression
)
对于以“:”结尾的语句,变化如下:
for foo in this_is_a_long_function_generating_an_iterable( here_are_some = arguments, and_they = are_long_too ):
print foo
变成:
for foo in this_is_a_long_function_generating_an_iterable(
here_are_some = arguments, and_they = are_long_too
):
print foo
但通常更清晰的写法是
foo_iter = this_is_a_long_function_generating_an_iterable(
here_are_some = arguments, and_they = are_long_too )
for foo in foo_iter:
print foo
或者
foo_iter = this_is_a_long_function_generating_an_iterable(
here_are_some = arguments, and_they = are_long_too
)
for foo in foo_iter:
print foo
最后一点:有些人认为这些规则已经过时,因为现在通常可以使用更大的窗口。我觉得这些规则仍然很有用,因为:
- 保持行短可以让我在更多的窗口(或编辑面板)中看到代码
- 上述方法展示了程序的逻辑结构
- 当换行不容易时,通常意味着用临时变量等方式会更好地展示结构
我有时候会遵循一个习惯,当常规的缩进风格让代码看起来太糟糕时,我会这样做:
filename = tkFileDialog.askopenfilename(
filetypes = (("Word list", "*.tldr"),("All files", "*.*"))
)
一开始看起来很奇怪。但它把多行结构的“头部”单独放在第一行,这样一眼就能看出来,而且也清楚地显示了多行结构在哪里结束。只缩进一个层级,而不是缩进到大括号的层级,这样可以给你更多的空间来写嵌套的代码。而且,这种方式还有一个好处,就是在你只改变函数参数时,代码的差异(diff)会很明显,这在某些情况下是很有用的。
在某种程度上,我觉得这种格式化习惯其实更适合现代的高级面向对象编程语言,而不是那些传统的风格,这些风格大多源于C语言;C语言没有链式调用,而且由于没有对象,函数名通常也比较短。但因为没有其他人使用这种风格,所以我把它当作备用方案,只有在正常风格让代码可读性变差时才会使用。
在我看来,选择短一点的代码行有一个好处,就是程序员更容易把代码拆分成一行一行的,这样每一行都更容易理解,也更容易发现错误或者找到更好的解决办法。
from __future__ import print_function
FMT_SAY_TEXT = '(SayText "%s")'
text_escaped = text.replace('\\', r'\\')
text_escaped = text_escaped.replace('"', r'\"')
text_out = FMT_SAY_TEXT % text_escaped
print(text_out, file=self.proc.stdin)
对于你的第二个例子:
FILE_DIALOG_FILETYPES = (("Word list", "*.tldr"), ("All files", "*.*"))
filename = tkFileDialog.askopenfilename(filetypes = FILE_DIALOG_FILETYPES)