这个Python语句的含义是什么?

1 投票
6 回答
4176 浏览
提问于 2025-04-17 08:58

更具体来说,我不太明白紧挨着的“%”和“\”这两个符号到底是什么意思:

return 'guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }' % \
    (self.id, a, b, c, d, e, f)

这个返回语句算不算是一行代码呢?因为我原本以为“\”是用来把看起来太长的代码分成两部分,以便更容易阅读,避免换行。

另外,这里的缩进确实和我代码里的缩进一致。那部分写着‘(self.id, a, b, c, d, e, f)’的确比返回语句的开头多缩进了一次。

基本上,这个语句是不是等同于:

return 'guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }' % (self.id, a, b, c, d, e, f)

在这个例子里没有“\”这个符号……

6 个回答

1

是的,你看到的其实是一个简单的字符串格式,它被分成了两行。反斜杠这个符号可以让你把Python的语句分成多行写,因为Python对空格和换行是很敏感的。

3

是的,行末的 \ 符号可以让换行符失效,所以这两段代码是等价的。

详细说明可以在这里找到: http://docs.python.org/reference/lexical_analysis.html#explicit-line-joining

6

%符号被称为字符串格式化字符串插值运算符,详细信息可以在字符串格式化操作中找到。需要注意的是,在我的例子中,我把%符号移到了下一行,而不是放在上一行的末尾。两种写法都是可以的,但把它放在和数据同一行通常会让代码更清晰,更容易维护。

是的,这两段代码是等效的,因为反斜杠会把两行或多行物理行当作一行逻辑行来处理,这在Python文档中关于\符号的显式行连接部分有说明。不过,我建议尽量避免使用显式行连接,而是使用第三种等效的方式,称为隐式行连接

return ('guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }'
        % (self.id, a, b, c, d, e, f))

这样在重新格式化时不容易出错,而且还可以使用注释,比如在这个重新格式化的例子中:

return ('guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }' 
        % (self.id, 
           a, 
           b, 
           # c1, 
           c2, 
           d, 
           e, 
           f))

试着用反斜杠做同样的事情……不仅更麻烦,而且你也不能使用注释。

需要注意的是,返回值周围的括号并不是多余的,正如一些人所说的;它们使得在变量插值的上下文中可以使用隐式行连接(这与%后面的元组是不同的上下文,隐式行连接也会在那发生):

用括号、方括号或大括号包围的表达式可以在不使用反斜杠的情况下跨越多行。

总之…… 请尽量避免使用反斜杠进行显式行连接!(考虑到其他选择,这几乎从来不是必要的)。

与显式/隐式行连接相关的主题是使用三重引号字符串,在字符串字面量部分有讨论。考虑到你吉他示例中的C风格块语法,我认为把你的返回值重新格式化为多行可能是有效的,如下所示:

class c(object):
    def f(self):
        return """
guitar {
  id: %d, 
  relevant_properties: (%.02f, %.02f, %.02f),
  irrelevant_properties: (%.02f, %.02f, %.02f)
}
""" % (self.id, a, b, c, d, e, f)

我把这个例子放在一个类方法定义的更完整的上下文中,这样会更清楚格式化的样子;多行字符串会紧贴缓冲区的左侧,任何空格都会原样出现在输出中。

不过要注意,上面的格式化可能会引入不必要的前导或尾随换行符,所以这是我偶尔推荐使用显式行连接的少数几种情况之一。这样做的原因是为了消除不必要的额外换行符,以换取三重引号字符串带来的更好的代码可读性,因为它让我们能够看到完整的段落,基本上就像我们在最终输出中看到的那样;对比上面的内容,你会看到在第一次出现"""的末尾只增加了一个\字符:

class c(object):
    def f(self):
        return """\
guitar {
  id: %d, 
  relevant_properties: (%.02f, %.02f, %.02f),
  irrelevant_properties: (%.02f, %.02f, %.02f)
}
""" % (self.id, a, b, c, d, e, f)

撰写回答