具有多个参数和类型提示的方法的挂起缩进的正确语法是什么?
在第一个参数下对齐
def get_library_book(self,
book_id: str,
library_id: str
)-> Book:
缩进下方一级
def get_library_book(
self,
book_id: str,
library_id: str
) -> Book:
PEP8 支持缩进,但不支持缩进,但不指定是否允许在第一个参数下对齐。它指出:
使用悬挂缩进时,应考虑以下事项; 第一行应该没有参数和进一步缩进 应该用于明确区分自己作为延续线。
PEP8 有很多好主意,但我不会依赖它来决定这种关于空格的问题。当我研究PEP8关于空白的建议时,我发现它们不一致,甚至相互矛盾。
相反,我会研究适用于几乎所有编程语言的一般原则,而不仅仅是Python。
第一个示例中显示的列对齐方式有许多缺点,我在任何项目中都不使用或允许它。
一些缺点:
- 如果更改函数名称以使其长度不同,则必须重新对齐所有参数。
- 执行该重新对齐时,源代码管理差异中会因不必要的空格更改而混乱。
- 随着代码的更新和维护,在重命名变量时可能会错过一些对齐方式,从而导致代码未对齐。
- 你会得到更长的线长度。
- 对齐方式在比例字体中不起作用。(是的,一些开发人员更喜欢比例字体,如果您避免列对齐,您的代码在等宽或比例字体中同样可读。
如果您在更复杂的情况下使用列对齐,情况会变得更糟。请考虑以下示例:
let mut rewrites = try_opt!(subexpr_list.iter()
.rev()
.map(|e| {
rewrite_chain_expr(e,
total_span,
context,
max_width,
indent)
})
.collect::<Option<Vec<_>>>());
这是来自伺服浏览器的 Rust 代码,其编码风格要求这种列对齐。虽然它不是Python代码,但完全相同的原则适用于Python或几乎任何语言。
在此代码示例中,应该很明显使用列对齐方式如何导致不良情况。如果您需要在嵌套rewrite_chain_expr
调用中调用另一个函数,或者具有更长的变量名称,该怎么办?除非你想要很长的队伍,否则你几乎没有空间了。
将上述版本与以下任何一个版本进行比较,这些版本使用纯粹基于缩进的样式,如第二个 Python 示例:
let mut rewrites = try_opt!(
subexpr_list
.iter()
.rev()
.map( |e| {
rewrite_chain_expr( e, total_span, context, max_width, indent )
})
.collect::<Option<Vec<_>>>()
);
或者,如果要rewrite_chain_expr
的参数更长,或者您只需要更短的行:
let mut rewrites = try_opt!(
subexpr_list
.iter()
.rev()
.map( |e| {
rewrite_chain_expr(
e,
total_span,
context,
max_width,
indent
)
})
.collect::<Option<Vec<_>>>()
);
与列对齐样式相比,这种纯缩进样式具有许多优点,根本没有缺点。
来自 Terrys 的 Appart 回答,举一个例子 typeshed
这是 Python GitHub 上的项目,用于用存根注释stdlib
。
例如,在importlib.machinery
(在其他情况下,如果您查看(注释是使用您的第一个表单完成的,例如:
def find_module(cls, fullname: str,
path: Optional[Sequence[importlib.abc._Path]]
) -> Optional[importlib.abc.Loader]:
更仔细地阅读 PEP 8 的前一行,"或使用悬挂缩进"之前的部分。
延续行应使用 Python 的隐式行在括号、括号和大括号内连接或使用悬挂缩进垂直对齐包装的元素。
这旨在涵盖第一个"是"示例,以及上面的第一个示例。
# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
var_three, var_four)